问题 在PowerShell中获取HTTP请求并容忍500服务器错误


在Powershell v3.0中,我想从HTTP GET返回响应代码,例如 200 OK 要么 500 Internal Server Error。 (这是为了进行黑客部署,对部署的站点进行快速预热并查看它是否有效,这是一种小型验收测试。状态代码确实是我想要的。)

违背我的意愿, HttpWebRequest.GetResponse 收到a时会抛出错误 500 Internal Server Error。这很烦人,因为在我的用例中对我来说并不是一个错误。无论如何,我认为我可以捕获异常并仍然剥离底层响应代码,但我遇到了麻烦。

这是一些几乎可以工作的代码:

function WebResponseStatusCode (
   [Parameter(Mandatory=$true)][string] $url
) {
    $req = [system.Net.HttpWebRequest]::Create($url)
    try {
        $res = $req.GetResponse();
        $statuscode = $res.statuscode;
    }
    catch [System.Net.WebException] {
        #the outer error is a System.Management.Automation.ErrorRecord
        Write-Host "error!"
        return = $_.Response.statuscode; #nope
    }
    finally {
        if (!($res -eq $null)) {
           $res.Close();
        }
    }
   return $statuscode;
}

问题当然是这样的 $_ 没有 Response 属性。也没有 $_.InnerException,即使是演员:

return [System.Net.WebException]($_.InnerException)

我玩过 $_ | Get-Member 并探索其所有属性。我想 $_.TargetObject 有一些承诺,但它似乎没有。

更新我也认为我试过变种 $_.Exception.Response 虽然可能弄错了。

获得响应代码似乎是一件非常简单的事情。


2739
2018-03-27 19:09


起源

我见过其他人遇到过这个问题。它应该被记录为增强请求 connect.microsoft.com 不要抛出5xx状态代码。 - Keith Hill
您是否在Invoke-WebRequest中看到相同的结果?我没有提供500个测试结果的服务器。 - Arluin
奇怪的是那个 Invoke-WebRequest 例如,处理这些错误的方式不同 Test-Connection (即ping)。 Test-Connection 使用 -ErrorVariable 和 -ErrorAction 正如你所料。 Invoke-WebRequest 只是打电话 Write-Error 什么时候出错了。 - oɔɯǝɹ


答案:


这是一个例子,虽然它允许您测试重定向以及预期的异常。

function GetWebSiteStatusCode {
    param (
        [string] $testUri,
        $maximumRedirection = 5
    )
    $request = $null
    try {
        $request = Invoke-WebRequest -Uri $testUri -MaximumRedirection $maximumRedirection -ErrorAction SilentlyContinue
    } 
    catch [System.Net.WebException] {
        $request = $_.Exception.Response

    }
    catch {
        Write-Error $_.Exception
        return $null
    }
    $request.StatusCode
}

GetWebSiteStatusCode -testUri "https://www.google.com/"
GetWebSiteStatusCode -testUri "https://www.google.com/foobar"
GetWebSiteStatusCode -testUri "http://google.com/" -maximumRedirection 0
GetWebSiteStatusCode -testUri "https://accounts.google.com" -maximumRedirection 0
GetWebSiteStatusCode -testUri "https://www.googleapis.com/coordinate/v1/teams/1/custom_fields?fields=1111&key="
GetWebSiteStatusCode -testUri "https://www.googleapis.com/shopping/search/v1/test/products/sasdf/asdf/asdf?key="

#Next test would be for an expected 500 page.
#GetWebSiteStatusCode -testUri "https://www.somesite.com/someurlthatreturns500"

16
2018-03-27 22:31



这很棒。我知道必须有一种方法可以更容易地做到这一点。太糟糕了,你仍然需要捕捉异常,但至少它正在工作!我不知道为什么我会尝试使用它 $_.Exception.Response 没用。 - ErikE
请注意,该异常返回一个 System.Net.HttpWebResponse不是 Microsoft.PowerShell.Commands.HtmlWebResponseObject,在我的测试中,似乎已经读取了响应流。 - hangar
我试过这个,它似乎适用于大多数错误代码。但是,当我应该收到12029(系统找不到指定的资源)代码时,这给了我一个0 ...请指教 - Michal Paszkiewicz
很好......诀窍是将捕获的异常强制转换为WebException - Jmoney38