捕获失败的响应/ 401 Invoke-WebRequest

时间:2017-02-14 16:37:35

标签: powershell

当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

$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   

3 个答案:

答案 0 :(得分:4)

这实际上是open issue on the PowerShell project on GitHub,但有一天可能会解决。

目前,我们倾向于解决这个问题。

首先,将此功能加载到内存中。

generalize

然后,像这样包装你的WebRequests。

Control.Monad.Morph

这种方法很酷的是它写了全局范围变量,它们会在你的函数退出后继续存在。当您遇到错误时,只需在return . runIdentityfunction 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 } 内查找完整错误。

在编写基于RPC或REST端点的模块时,这是必须的。

此信用technique goes to Steve Wahl.

答案 1 :(得分:2)

我发现你可以在try / catch块中捕获Response。

try
{
    $Response = Invoke-WebRequest -Method HEAD -Uri 'https://site.contoso.com'
}
catch
{
    $Failure = $_.Exception.Response
}

但是,这只有在您捕获它并查看运行时的响应时才有效。您无法从$ Error变量中检索响应数据。

答案 2 :(得分:0)

由于abhinavsingh003在https://github.com/PowerShell/PowerShell/issues/2193上找到了另一个答复!

Try {
     $WebRequestResult = Invoke-RestMethod -Uri $URL -Headers $Headers -Body $BodyJSON -Method $Method -ContentType $ContentType -SkipCertificateCheck
     Write-Host $WebRequestResult
} Catch {
    if($_.ErrorDetails.Message) {
        "----WebResponseError----"
        Write-Host $_.ErrorDetails.Message;
    } else {
        #UsualException
        $_
    }
}

您可能会从i9shankar的网站中找到正确的Invoke-RestMethod / Invoke-WebRequest Powershell BitBucket项目: https://github.com/i9shankar/ps-bitbucket/blob/88edaf469014da16179bb7b215f3fbad04bf2373/Private/Invoke-BitBucketWebRequest.ps1