当 Invoke-WebRequest 达到 500、401、403 等时,如何捕获输出?当调用成功时,它将结果存储在$Response变量中,但是如果我遇到 401,它会抛出错误但不存储响应。
$Response = Invoke-WebRequest -Method HEAD -Uri 'https://site.contoso.com'
Invoke-WebRequest : The remote server returned an error: (401) Unauthorized.
At line:1 char:13
+ $Response = Invoke-WebRequest -Method HEAD -Uri 'https://site.contoso.com' -Erro ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest], WebException
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand
Run Code Online (Sandbox Code Playgroud)
该$Response变量仍然为空,但是端点返回 401 Unauthorized和标头,它只是没有被 PowerShell 捕获,因为它将其视为异常。通过 Fiddler 进行管道传输证实了这一点。
创建使用请求[System.Net.WebRequest]具有当我执行相同的结果$Response = $WebRequest.GetResponse()。
这是我的$PSVersionTable。
Name Value
---- -----
PSVersion 4.0
WSManStackVersion 3.0
SerializationVersion 1.1.0.1
CLRVersion 4.0.30319.36373
BuildVersion 6.3.9600.16406
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0}
PSRemotingProtocolVersion 2.2
Run Code Online (Sandbox Code Playgroud)
这实际上是GitHub 上 PowerShell 项目上的一个未解决的问题,但它可能有一天会得到解决。
现在,这是我们倾向于解决这个问题的方法。
首先,将此函数加载到内存中。
function Failure {
$global:helpme = $body
$global:helpmoref = $moref
$global:result = $_.Exception.Response.GetResponseStream()
$global:reader = New-Object System.IO.StreamReader($global:result)
$global:responseBody = $global:reader.ReadToEnd();
Write-Host -BackgroundColor:Black -ForegroundColor:Red "Status: A system exception was caught."
Write-Host -BackgroundColor:Black -ForegroundColor:Red $global:responsebody
Write-Host -BackgroundColor:Black -ForegroundColor:Red "The request body has been saved to `$global:helpme"
break
}
Run Code Online (Sandbox Code Playgroud)
然后,像这样包装您的 WebRequest。
try
{
$Response = Invoke-WebRequest -Method HEAD -Uri 'https://site.contoso.com'
}
catch
{
Failure
}
Run Code Online (Sandbox Code Playgroud)
这种方法很酷的一点是它编写了全局作用域变量,并且它们会在您的函数退出后持续存在。当您确实遇到错误时,只需在内部$global:result或$global:responsebody完整错误中戳一下。
这是编写基于 RPC 或 REST 端点的模块时必须具备的。
| 归档时间: |
|
| 查看次数: |
9205 次 |
| 最近记录: |