Invoke-WebRequest在Win PowerShell5.1报401认证失败 PowerShell7正常
你的判断完全准确,故障确实由密码中的变音字符编码不匹配导致:
Windows PowerShell 5.1 的Invoke-WebRequest基于.NET Framework 旧版HttpWebRequest实现,通过-Credential参数自动生成Basic认证头时,会使用系统默认ANSI代码页编码凭据内容,不符合HTTP Basic认证要求的UTF-8/ISO-8859-1编码规范。包含变音字符的密码转码后和实际输入值不一致,Artifactory校验不通过就会返回401错误。PowerShell 7+基于.NET Core重构了HTTP栈,默认用UTF-8处理凭据,因此可以正常运行。
任选一种即可生效:
手动构造标准编码的认证头,绕开内置cmdlet的编码bug
保留原有的凭据弹窗交互逻辑,不需要修改系统配置,是最稳妥的方案:$dest = 'https://artifactory.****.de/artifactory/*********/' $cred = Get-Credential # 按UTF-8编码生成Basic认证头 $base64Auth = [Convert]::ToBase64String( [Text.Encoding]::UTF8.GetBytes("$($cred.UserName):$($cred.GetNetworkCredential().Password)") ) $requestHeaders = @{ Authorization = "Basic $base64Auth" } Invoke-WebRequest -Uri $dest -Headers $requestHeaders如果UTF-8编码仍返回401,把代码中
[Text.Encoding]::UTF8替换为[Text.Encoding]::GetEncoding('ISO-8859-1')即可,部分旧版本Artifactory会要求用Latin1编码解析Basic认证头。修改当前会话的HTTP默认编码
不需要调整原有请求代码,仅对当前PowerShell窗口生效,不影响系统全局配置:# 配置当前会话HTTP请求默认使用UTF-8编码 [System.Net.HttpWebRequest]::DefaultEncoding = [Text.Encoding]::UTF8 # 执行原有命令即可正常识别带变音的密码 $dest = 'https://artifactory.****.de/artifactory/*********/' Invoke-WebRequest -Uri $dest -Credential (Get-Credential)开启系统全局UTF-8支持(不推荐优先使用)
Windows 10 1809及以上版本可在「控制面板-区域-管理-更改系统区域设置」中勾选「Beta版:使用Unicode UTF-8提供全球语言支持」,重启后系统默认ANSI编码变为UTF-8,该问题会自动消失。但该配置会影响所有依赖旧ANSI编码的本地程序,可能引发其他软件乱码问题。
注意:所有方案均保留了凭据弹窗输入的交互逻辑,不要将密码硬编码在脚本中,避免明文泄露风险。
内容的提问来源于stack exchange,提问作者AxD

