PowerShell使用WebClient.UploadFile上传文件到HTTPS站点报错排查
报错核心原因
抛出的通用WebClient请求异常,在HTTPS文件上传场景下通常由以下问题触发:
- TLS版本不兼容:PowerShell 5.1默认启用TLS 1.0协议,当前绝大多数HTTPS站点已拒绝该版本的握手请求,连接建立阶段直接失败
- HTTPS证书校验拦截:内部开发站点
dev.loin.com通常使用自签名SSL证书,未加入系统受信任根证书存储,WebClient默认会直接终止不受信任证书的HTTPS请求 - 上传协议不匹配:原脚本直接使用PUT方法上传裸文件流,但大部分Web上传接口要求使用
multipart/form-data格式的POST请求提交文件,不接受裸PUT流 - 认证逻辑不匹配:原脚本使用Windows集成认证的
NetworkCredential传参,如果站点使用Basic认证、表单Token认证,该参数不会被正确带入请求头,请求会被服务端权限拦截 - 冗余URL拼接错误:原脚本手动拼接上传地址为
https://dev.loin.com/upload/logggz.zip,大部分上传接口不需要在路径中指定目标文件名,错误的路径会直接返回404触发异常
修正后的可运行上传脚本
以下版本已覆盖上述所有问题点,适配绝大多数内部开发HTTPS站点场景:
# 基础HTTPS配置:强制使用TLS1.2协议,跳过开发环境自签名证书校验(生产环境请删除证书回调代码) [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 [Net.ServicePointManager]::ServerCertificateValidationCallback = {$true} $SourceFilePath = "C:\Users\Ulis\Desktop\logggz.zip" $SiteAddress = "https://dev.loin.com/upload" $MyUsername = "ulis" $MyPassword = "userAccSite" Function Upload-File { Param ( [string]$File, [string]$URI, [string]$Username, [string]$Password ) # 前置校验:确认本地待上传文件存在 if (-not (Test-Path $File -PathType Leaf)) { throw "待上传文件路径无效:$File" } $WebClient = New-Object System.Net.WebClient # 默认使用HTTP Basic认证,适配绝大多数简单鉴权场景 $base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes("{0}:{1}" -f $Username,$Password)) $WebClient.Headers.Add("Authorization", "Basic $base64AuthInfo") # 如果站点使用Windows域集成认证,注释上面两行,取消注释下面这行即可 # $WebClient.Credentials = New-Object System.Net.NetworkCredential($Username,$Password) ("*** 正在上传 {0} 到 {1} ***" -f ($File, $URI)) | Write-Host -ForegroundColor Green # 默认使用POST multipart/form-data格式上传,适配90%以上的标准Web上传接口 $response = $WebClient.UploadFile($URI, "POST", $File) # 输出服务端返回结果便于排查 Write-Host "服务端响应:$([Text.Encoding]::UTF8.GetString($response))" -ForegroundColor Cyan # 如果确认接口支持PUT裸文件流上传,注释上面两行POST相关代码,取消注释下面这行 # $WebClient.UploadFile($URI, "PUT", $File) } Upload-File -File $SourceFilePath -URI $SiteAddress -Username $MyUsername -Password $MyPassword
调整说明
- 移除原脚本冗余的URL拼接逻辑,直接向官方上传接口地址提交请求即可,不需要手动在路径中拼接目标文件名
- 脚本开头强制指定TLS1.2协议,解决HTTPS握手失败问题
- 内置自签名证书跳过逻辑,适配内部开发环境的未受信证书场景
- 内置两种认证方式切换开关,可根据站点实际鉴权逻辑快速切换
- 新增本地文件存在校验、服务端响应输出逻辑,减少无意义的报错排查成本
- 内置两种上传方法切换开关,可根据接口实际要求快速切换POST/PUT方法
注意:跳过证书校验的逻辑仅允许在内部开发测试环境使用,公网生产环境请删除
ServerCertificateValidationCallback相关代码,避免中间人攻击风险。
内容的提问来源于stack exchange,提问作者SySx
相关产品推荐
相关产品推荐

