小蓝窗:“PS C:\Users\Administrator> # 创建模块目录
PS C:\Users\Administrator> $moduleName = "PSHttpClient"
PS C:\Users\Administrator> $moduleVersion = "1.2.0"
PS C:\Users\Administrator> $moduleDir = "$env:ProgramFiles\WindowsPowerShell\Modules\$moduleName\$moduleVersion"
PS C:\Users\Administrator> New-Item -Path $moduleDir -ItemType Directory -Force | Out-Null
PS C:\Users\Administrator>
PS C:\Users\Administrator> # 创建模块文件
PS C:\Users\Administrator> $moduleContent = @'
>> # 加载必要程序集(兼容 .NET 9 和旧版)
>> try {
>> Add-Type -AssemblyName System.Net.Http -ErrorAction Stop
>> } catch {
>> [System.Reflection.Assembly]::LoadWithPartialName("System.Net.Http") | Out-Null
>> }
>>
>> # 检测 .NET 版本
>> $dotnetVersion = [System.Environment]::Version
>> $isNet9OrNewer = $dotnetVersion.Major -ge 9 -or ($dotnetVersion.Major -eq 8 -and $dotnetVersion.Minor -ge 0)
>>
>> function Invoke-EnhancedCurlRequest {
>> [CmdletBinding()]
>> param(
>> [Parameter(Mandatory=$true)]
>> [string]$Uri,
>> [ValidateSet('GET','POST','PUT','DELETE','PATCH','HEAD','OPTIONS')]
>> [string]$Method = 'GET',
>> [hashtable]$Headers = @{},
>> [object]$Body,
>> [int]$Timeout = 30,
>> [switch]$SkipCertificateCheck,
>> [switch]$UseGzipCompression,
>> [switch]$EnableHttp2
>> )
>>
>> # 使用强类型结果模板
>> $resultTemplate = [PSCustomObject]@{
>> StatusCode = 0
>> StatusMessage = "NotExecuted"
>> Headers = [ordered]@{}
>> Content = $null
>> IsSuccess = $false
>> Technology = "None"
>> ErrorMessage = $null
>> ElapsedMs = 0
>> Protocol = "Unknown"
>> DotnetVersion = $dotnetVersion.ToString()
>> }
>>
>> $timer = [System.Diagnostics.Stopwatch]::StartNew()
>> $result = $resultTemplate.PSObject.Copy()
>>
>> # 重构证书检测逻辑
>> $useHttpClient = $true
>> $oldCallback = $null
>>
>> if ($SkipCertificateCheck) {
>> try {
>> # 正确的证书验证检测方式
>> $testHandler = New-Object System.Net.Http.HttpClientHandler
>> $testHandler.ServerCertificateCustomValidationCallback = {
>> param($sender, $cert, $chain, $errors)
>> return $true
>> }
>> } catch {
>> $useHttpClient = $false
>> }
>> }
>>
>> if ($useHttpClient) {
>> # ======================== .NET 9 优化实现 ========================
>> $result.Technology = "HttpClient(.NET $($dotnetVersion.Major))"
>>
>> try {
>> # 创建 HttpClientHandler
>> $handler = New-Object System.Net.Http.HttpClientHandler
>>
>> # .NET 9 特有的优化特性
>> if ($isNet9OrNewer) {
>> # 启用 HTTP/2 或 HTTP/3
>> $handler.MaxConnectionsPerServer = 10
>> $handler.PooledConnectionLifetime = [System.TimeSpan]::FromMinutes(1)
>>
>> if ($EnableHttp2) {
>> $handler.DefaultVersionPolicy = [System.Net.Http.HttpVersionPolicy]::RequestVersionOrHigher
>> $handler.DefaultRequestVersion = [System.Version]::new(2, 0)
>> }
>> }
>>
>> # 证书验证
>> if ($SkipCertificateCheck) {
>> $handler.ServerCertificateCustomValidationCallback = {
>> param($sender, $cert, $chain, $errors)
>> return $true
>> }
>> }
>>
>> # 压缩支持
>> if ($UseGzipCompression) {
>> $handler.AutomaticDecompression = [System.Net.DecompressionMethods]::GZip
>> }
>>
>> # 创建 HttpClient
>> $client = New-Object System.Net.Http.HttpClient($handler)
>> $client.Timeout = [System.TimeSpan]::FromSeconds($Timeout)
>>
>> # 修复3:正确创建HttpMethod对象
>> $httpMethod = [System.Net.Http.HttpMethod]::new($Method)
>> $request = New-Object System.Net.Http.HttpRequestMessage($httpMethod, $Uri)
>>
>> # 协议版本设置
>> if ($isNet9OrNewer -and $EnableHttp2) {
>> $request.Version = [System.Version]::new(2, 0)
>> $request.VersionPolicy = [System.Net.Http.HttpVersionPolicy]::RequestVersionOrHigher
>> }
>>
>> # 添加默认 User-Agent
>> if (-not $Headers.ContainsKey('User-Agent')) {
>> $request.Headers.TryAddWithoutValidation("User-Agent", "PowerShell-HTTPClient/1.0 (.NET $($dotnetVersion.Major))")
>> }
>>
>> # 添加自定义头
>> foreach ($key in $Headers.Keys) {
>> if (-not $request.Headers.TryAddWithoutValidation($key, $Headers[$key])) {
>> # 如果头字段无法添加到请求头,尝试添加到内容头
>> if (-not $request.Content) {
>> $request.Content = New-Object System.Net.Http.StringContent("")
>> }
>> $request.Content.Headers.TryAddWithoutValidation($key, $Headers[$key])
>> }
>> }
>>
>> # 处理请求体
>> if ($Body -and @('POST','PUT','PATCH') -contains $Method) {
>> if ($Body -is [byte[]]) {
>> $request.Content = New-Object System.Net.Http.ByteArrayContent($Body)
>> }
>> elseif ($Body -is [hashtable] -or $Body -is [System.Collections.IDictionary]) {
>> $jsonBody = $Body | ConvertTo-Json -Depth 10 -Compress
>> $request.Content = New-Object System.Net.Http.StringContent(
>> $jsonBody,
>> [System.Text.Encoding]::UTF8,
>> "application/json"
>> )
>> }
>> elseif ($Body -is [string]) {
>> $request.Content = New-Object System.Net.Http.StringContent(
>> $Body,
>> [System.Text.Encoding]::UTF8
>> )
>> }
>> else {
>> throw "Unsupported body type: $($Body.GetType().Name)"
>> }
>> }
>>
>> # 发送请求(异步转同步)
>> $response = $client.SendAsync($request).GetAwaiter().GetResult()
>>
>> # 记录实际使用的协议
>> $result.Protocol = "HTTP/" + $response.Version.ToString()
>>
>> # 解析响应
>> $result.StatusCode = [int]$response.StatusCode
>> $result.StatusMessage = $response.ReasonPhrase
>> $result.IsSuccess = $response.IsSuccessStatusCode
>>
>> # 处理响应头
>> $result.Headers = [ordered]@{}
>> foreach ($header in $response.Headers) {
>> $result.Headers[$header.Key] = $header.Value -join ", "
>> }
>>
>> foreach ($header in $response.Content.Headers) {
>> $result.Headers[$header.Key] = $header.Value -join ", "
>> }
>>
>> # 读取响应内容
>> $result.Content = $response.Content.ReadAsStringAsync().GetAwaiter().GetResult()
>> }
>> catch [System.Threading.Tasks.TaskCanceledException] {
>> $result.ErrorMessage = "Request timed out after $Timeout seconds"
>> $result.StatusCode = 408
>> $result.StatusMessage = "Timeout"
>> }
>> catch [System.Net.Http.HttpRequestException] {
>> # 增强的错误处理
>> $ex = $_.Exception
>> $result.ErrorMessage = $ex.ToString()
>>
>> # 检查具体错误类型
>> $dnsError = $false
>> $sslError = $false
>>
>> if ($isNet9OrNewer) {
>> # .NET 9 提供更精确的错误类型
>> if ($ex.InnerException -is [System.Net.Sockets.SocketException]) {
>> $dnsError = $true
>> }
>> elseif ($ex.InnerException -is [System.Security.Authentication.AuthenticationException]) {
>> $sslError = $true
>> }
>> } else {
>> # 旧版兼容性处理
>> $currentException = $ex
>> while ($currentException -ne $null) {
>> if ($currentException -is [System.Net.Sockets.SocketException]) {
>> $dnsError = $true
>> break
>> }
>> if ($currentException -is [System.Security.Authentication.AuthenticationException]) {
>> $sslError = $true
>> break
>> }
>> $currentException = $currentException.InnerException
>> }
>> }
>>
>> if ($dnsError) {
>> $result.StatusCode = 0
>> $result.StatusMessage = "DNSResolutionFailed"
>> }
>> elseif ($sslError) {
>> $result.StatusCode = 495
>> $result.StatusMessage = "SSLCertificateError"
>> }
>> else {
>> $result.StatusCode = 500
>> $result.StatusMessage = "HttpRequestError"
>> }
>> }
>> catch {
>> $result.ErrorMessage = $_.Exception.ToString()
>> $result.StatusCode = 500
>> $result.StatusMessage = "InternalError"
>> }
>> finally {
>> # 释放资源
>> if ($response -is [System.IDisposable]) { $response.Dispose() }
>> if ($request -is [System.IDisposable]) { $request.Dispose() }
>> if ($client -is [System.IDisposable]) { $client.Dispose() }
>> if ($handler -is [System.IDisposable]) { $handler.Dispose() }
>> }
>> }
>> else {
>> # ======================== 备用实现(兼容旧版) ========================
>> $result.Technology = "HttpWebRequest"
>>
>> try {
>> # 设置全局证书验证回调
>> if ($SkipCertificateCheck) {
>> $oldCallback = [System.Net.ServicePointManager]::ServerCertificateValidationCallback
>> [System.Net.ServicePointManager]::ServerCertificateValidationCallback = {
>> param($sender, $certificate, $chain, $sslPolicyErrors)
>> return $true
>> }
>> }
>>
>> # 创建请求
>> $request = [System.Net.HttpWebRequest]::Create($Uri)
>> $request.Method = $Method
>> $request.Timeout = $Timeout * 1000
>>
>> # 添加默认 User-Agent
>> if (-not $Headers.ContainsKey('User-Agent')) {
>> $request.UserAgent = "PowerShell-HTTPClient/1.0 (Legacy)"
>> }
>>
>> # 添加自定义头
>> foreach ($极 in $Headers.Keys) {
>> $request.Headers.Add($key, $Headers[$key])
>> }
>>
>> # 处理请求体
>> if ($Body -and @('POST','PUT','PATCH') -contains $Method) {
>> $request.ContentType = "application/json"
>> $bodyBytes = [System.Text.Encoding]::UTF8.GetBytes(($Body | ConvertTo-Json -Depth 10 -Compress))
>> $request.ContentLength = $bodyBytes.Length
>>
>> $requestStream = $request.GetRequestStream()
>> $requestStream.Write($bodyBytes, 0, $bodyBytes.Length)
>> $requestStream.Close()
>> }
>>
>> # 发送请求并获取响应
>> $response = $request.GetResponse()
>> $result.StatusCode = [int]$response.StatusCode
>> $result.StatusMessage = $极.Response.StatusDescription
>> $result.IsSuccess = $result.StatusCode -ge 200 -and $result.StatusCode -lt 300
>>
>> # 读取响应头
>> $result.Headers = [ordered]@{}
>> foreach ($key in $response.Headers.AllKeys) {
>> $result.Headers[$key] = $response.Headers[$key]
>> }
>>
>> # 读取响应体
>> $responseStream = $response.GetResponseStream()
>> $reader = New-Object System.IO.StreamReader($responseStream)
>> $result.Content = $reader.ReadToEnd()
>> $reader.Close()
>> $response.Close()
>> }
>> catch [System.Net.WebException] {
>> $ex = $_.Exception
>> $result.ErrorMessage = $ex.ToString()
>>
>> if ($ex.Response -ne $null) {
>> $httpResponse = $ex.Response
>> $result.StatusCode = [int]$httpResponse.StatusCode
>> $result.StatusMessage = $httpResponse.StatusDescription
>>
>> # 读取错误响应体
>> $errorStream = $httpResponse.GetResponseStream()
>> $errorReader = New-Object System.IO.StreamReader($errorStream)
>> $result.Content = $errorReader.ReadToEnd()
>> $errorReader.Close()
>> }
>> else {
>> # 检查具体错误类型
>> if ($ex.Status -eq [System.Net.WebExceptionStatus]::NameResolutionFailure) {
>> $result.StatusCode = 0
>> $result.StatusMessage = "DNSResolutionFailed"
>> }
>> elseif ($ex.Status -eq [System.Net.WebExceptionStatus]::TrustFailure) {
>> $result.Status极 = 495
>> $result.StatusMessage = "SSLCertificateError"
>> }
>> elseif ($ex.Status -eq [System.Net.WebExceptionStatus]::Timeout) {
>> $result.StatusCode = 408
>> $result.StatusMessage = "Timeout"
>> }
>> else {
>> $result.StatusCode = 500
>> $result.StatusMessage = "WebException"
>> }
>> }
>> }
>> catch {
>> $result.ErrorMessage = $_.Exception.ToString()
>> $result.StatusCode = 500
>> $result.StatusMessage = "InternalError"
>> }
>> finally {
>> # 恢复全局证书验证回调
>> if ($SkipCertificateCheck) {
>> [System.Net.ServicePointManager]::ServerCertificateValidationCallback = $oldCallback
>> }
>> }
>> }
>>
>> $timer.Stop()
>> $result.ElapsedMs = $timer.ElapsedMilliseconds
>> return $result
>> }
>>
>> # 导出模块成员
>> Export-ModuleMember -Function Invoke-EnhancedCurlRequest
>> '@
>>
PS C:\Users\Administrator> $moduleContent | Out-File "$moduleDir\PSHttpClient.psm1" -Encoding UTF8 -Force
PS C:\Users\Administrator>
PS C:\Users\Administrator> # 创建模块清单文件
PS C:\Users\Administrator> $manifestContent = @"
>> @{
>> RootModule = 'PSHttpClient.psm1'
>> ModuleVersion = '$moduleVersion'
>> GUID = 'd1c2b3a4-5e6f-7g8h-9i0j-1k2l3m4n5o6p'
>> Author = 'PowerShell User'
>> CompanyName = 'N/A'
>> Copyright = '(c) 2023. All rights reserved.'
>> Description = 'Enhanced HTTP client for PowerShell with .NET 9 support'
>> PowerShellVersion = '5.1'
>> FunctionsToExport = @('Invoke-EnhancedCurlRequest')
>> RequiredAssemblies = @('System.Net.Http')
>> }
>> "@
>>
PS C:\Users\Administrator> $manifestContent | Out-File "$moduleDir\PSHttpClient.psd1" -Encoding UTF8 -Force
PS C:\Users\Administrator>
PS C:\Users\Administrator> # 安装完成,导入模块
PS C:\Users\Administrator> Write-Host "`n=== 模块安装成功 ===" -ForegroundColor Green
=== 模块安装成功 ===
PS C:\Users\Administrator> Write-Host "模块路径: $moduleDir" -ForegroundColor Cyan
模块路径: C:\Program Files\WindowsPowerShell\Modules\PSHttpClient\1.2.0
PS C:\Users\Administrator> Write-Host "版本: $moduleVersion" -ForegroundColor Cyan
版本: 1.2.0
PS C:\Users\Administrator> Write-Host ".NET 版本: $dotnetVersion" -ForegroundColor Cyan
.NET 版本:
PS C:\Users\Administrator>
PS C:\Users\Administrator> # 导入模块
PS C:\Users\Administrator> Remove-Module PSHttpClient -ErrorAction SilentlyContinue
PS C:\Users\Administrator> Import-Module "$moduleDir\PSHttpClient.psm1" -Force -Verbose
详细信息: 正在从路径“C:\Program Files\WindowsPowerShell\Modules\PSHttpClient\1.2.0\PSHttpClient.psm1”加载模块。
详细信息: 正在导入函数“Invoke-EnhancedCurlRequest”。
PS C:\Users\Administrator>
PS C:\Users\Administrator> # 验证安装
PS C:\Users\Administrator> if (Get-Command Invoke-EnhancedCurlRequest -ErrorAction SilentlyContinue) {
>> Write-Host "`n=== 功能验证 ===" -ForegroundColor Green
>> Write-Host "测试基本请求: https://httpbin.org/get"
>> $result = Invoke-EnhancedCurlRequest -Uri "https://httpbin.org/get"
>> Write-Host "状态码: $($result.StatusCode) $($result.StatusMessage)"
>> Write-Host "技术: $($result.Technology)"
>> Write-Host "协议: $($result.Protocol)"
>> Write-Host "耗时: $($result.ElapsedMs)ms"
>>
>> Write-Host "`n=== 模块已成功安装并导入 ===" -ForegroundColor Green
>> } else {
>> Write-Host "`n!!! 模块安装失败 !!!" -ForegroundColor Red
>> Write-Host "请检查错误信息并重试" -ForegroundColor Red
>> }
>>
=== 功能验证 ===
测试基本请求: https://httpbin.org/get
状态码: 200 OK
技术: HttpClient(.NET 4)
协议: HTTP/1.1
耗时: 1155ms
=== 模块已成功安装并导入 ===
PS C:\Users\Administrator> # 导入模块(如果未自动导入)
PS C:\Users\Administrator> Import-Module PSHttpClient -Force
Import-Module : 模块清单文件“C:\Program Files\WindowsPowerShell\Modules\PSHttpClient\1.2.0\PSHttpClient.psd1”中的“gu
id”成员无效: 无法将值“d1c2b3a4-5e6f-7g8h-9i0j-1k2l3m4n5o6p”转换为类型“System.Guid”。错误:“Guid 字符串只应包含十六
进制字符。”
所在位置 行:1 字符: 1
+ Import-Module PSHttpClient -Force
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ResourceUnavailable: (C:\Program File...HttpClient.psd1:String) [Import-Module], Argumen
tException
+ FullyQualifiedErrorId : Modules_InvalidManifest,Microsoft.PowerShell.Commands.ImportModuleCommand
PS C:\Users\Administrator>
PS C:\Users\Administrator> # 基本GET请求
PS C:\Users\Administrator> $result = Invoke-EnhancedCurlRequest -Uri "https://httpbin.org/get"
Invoke-EnhancedCurlRequest : 无法将“Invoke-EnhancedCurlRequest”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请
检查名称的拼写,如果包括路径,请确保路径正确,然后再试一次。
所在位置 行:1 字符: 11
+ $result = Invoke-EnhancedCurlRequest -Uri "https://httpbin.org/get"
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (Invoke-EnhancedCurlRequest:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
PS C:\Users\Administrator> $result | Format-List
True
StatusCode : 200
StatusMessage : OK
Headers : {Connection, Access-Control-Allow-Origin, Access-Control-Allow-Credentials, Date...}
Content : {
"args": {},
"headers": {
"Host": "httpbin.org",
"User-Agent": "PowerShell-HTTPClient/1.0 (.NET 4)",
"X-Amzn-Trace-Id": "Root=1-68a07c9b-3da8c8115bd19c2018aaa3c8"
},
"origin": "112.40.123.16",
"url": "https://httpbin.org/get"
}
IsSuccess : True
Technology : HttpClient(.NET 4)
ErrorMessage :
ElapsedMs : 1155
Protocol : HTTP/1.1
DotnetVersion : 4.0.30319.42000
PS C:\Users\Administrator>
PS C:\Users\Administrator> # POST请求示例
PS C:\Users\Administrator> $postData = @{
>> name = "John Doe"
>> age = 30
>> email = "john.doe@example.com"
>> }
>> $result = Invoke-EnhancedCurlRequest -Uri "https://httpbin.org/post" -Method POST -Body $postData
>> $result.Content | ConvertFrom-Json | Format-List
>>
Invoke-EnhancedCurlRequest : 无法将“Invoke-EnhancedCurlRequest”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请
检查名称的拼写,如果包括路径,请确保路径正确,然后再试一次。
所在位置 行:6 字符: 11
+ $result = Invoke-EnhancedCurlRequest -Uri "https://httpbin.org/post" ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (Invoke-EnhancedCurlRequest:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
args :
headers : @{Host=httpbin.org; User-Agent=PowerShell-HTTPClient/1.0 (.NET 4); X-Amzn-Trace-Id=Root=1-68a07c9b-3da8c8115b
d19c2018aaa3c8}
origin : 112.40.123.16
url : https://httpbin.org/get
PS C:\Users\Administrator> # 忽略证书验证
PS C:\Users\Administrator> $result = Invoke-EnhancedCurlRequest -Uri "https://self-signed.badssl.com/" -SkipCertificateCheck
Invoke-EnhancedCurlRequest : 无法将“Invoke-EnhancedCurlRequest”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请
检查名称的拼写,如果包括路径,请确保路径正确,然后再试一次。
所在位置 行:1 字符: 11
+ $result = Invoke-EnhancedCurlRequest -Uri "https://self-signed.badssl ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (Invoke-EnhancedCurlRequest:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
PS C:\Users\Administrator> $result | Format-List
True
StatusCode : 200
StatusMessage : OK
Headers : {Connection, Access-Control-Allow-Origin, Access-Control-Allow-Credentials, Date...}
Content : {
"args": {},
"headers": {
"Host": "httpbin.org",
"User-Agent": "PowerShell-HTTPClient/1.0 (.NET 4)",
"X-Amzn-Trace-Id": "Root=1-68a07c9b-3da8c8115bd19c2018aaa3c8"
},
"origin": "112.40.123.16",
"url": "https://httpbin.org/get"
}
IsSuccess : True
Technology : HttpClient(.NET 4)
ErrorMessage :
ElapsedMs : 1155
Protocol : HTTP/1.1
DotnetVersion : 4.0.30319.42000
PS C:\Users\Administrator>
PS C:\Users\Administrator> # 启用HTTP/2
PS C:\Users\Administrator> $result = Invoke-EnhancedCurlRequest -Uri "https://http2.pro/api/v1" -EnableHttp2
Invoke-EnhancedCurlRequest : 无法将“Invoke-EnhancedCurlRequest”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请
检查名称的拼写,如果包括路径,请确保路径正确,然后再试一次。
所在位置 行:1 字符: 11
+ $result = Invoke-EnhancedCurlRequest -Uri "https://http2.pro/api/v1" ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (Invoke-EnhancedCurlRequest:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
PS C:\Users\Administrator> Write-Host "使用的协议: $($result.Protocol)"
使用的协议: HTTP/1.1
PS C:\Users\Administrator>”
如果你需要我储存文件 请告诉我文件储存的路径 不然我存不了
最新发布