PowerShell Invoke-WebRequest引发WebCmdletResponseException

tin*_*ker 2 powershell ssl httpwebrequest servicepointmanager tls1.2

执行该行时,Invoke-WebRequest -Uri https://www.freehaven.net/anonbib/date.htmlPowerShell throws抛出WebCmdletResponseException。我如何获得有关它的更多信息,这可能是什么原因造成的?虽然我可以使用Python成功获取页面的内容,但是在PowerShell中会引发异常。

完全例外:

Invoke-WebRequest : The underlying connection was closed: An unexpected error occurred on a send.
At line:1 char:1
+ Invoke-WebRequest -Uri https://www.freehaven.net/anonbib/date.html
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest], WebExc
   eption
    + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand
Run Code Online (Sandbox Code Playgroud)

bri*_*ist 5

这是因为在幕后Invoke-WebRequest使用HttpWebRequest,除最新版本的.Net以外,其他默认情况下均默认使用SSLv3和TLSv1。

您可以通过查看当前值来查看:

[System.Net.ServicePointManager]::SecurityProtocol
Run Code Online (Sandbox Code Playgroud)

您要连接站点仅支持TLS 1.2

您可以更改允许的协议,但是它在应用程序运行期间全局适用:

[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12
Run Code Online (Sandbox Code Playgroud)

这将覆盖该值。

当然,这将破坏应用程序中依赖于与不支持TLS 1.2的服务器的连接的任何其他内容

一种安全的方法可能是添加 TLS 1.2:

[System.Net.ServicePointManager]::SecurityProtocol] = (
    [System.Net.ServicePointManager]::SecurityProtocol -bor 
    [System.Net.SecurityProtocolType]::Tls12
)

# parentheses are for readability
Run Code Online (Sandbox Code Playgroud)

在偶然的情况下,这仍然会导致其他站点出现问题(不确定什么,也许某个站点说它接受TLS 1.2,但其实现被破坏,而TLS 1.0正常工作?),您可以保存以前的值并恢复它。

$cur = [System.Net.ServicePointManager]::SecurityProtocol]
try {
    [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12
    Invoke-WebRequest -Uri https://www.freehaven.net/anonbib/date.html
} finally {
    [System.Net.ServicePointManager]::SecurityProtocol = $cur
}
Run Code Online (Sandbox Code Playgroud)

  • 很好的答案,正是我需要的原因和修复! (2认同)