Search code examples
powershellhttp-request

Get HTTP request and tolerate 500 server error in powershell


In Powershell v3.0 I would like to return the response code from an HTTP GET, such as 200 OK or 500 Internal Server Error. (This is for a hack-deploy to do a quick warmup of a deployed site and see if it works, a sort of a mini acceptance test. The status code is truly all I want.)

Against my wishes, HttpWebRequest.GetResponse throws an error when it receives a 500 Internal Server Error. This is annoying because it isn't really an error to me in my use case. Anyway, I figured I could catch the exception and still peel out the underlying response code, but I'm having trouble with that.

Here's some almost-working code:

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;
}

The problem is of course that $_ has no Response property. Neither does $_.InnerException, even when cast:

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

I've played around with $_ | Get-Member and exploring all its properties. I thought $_.TargetObject had some promise but it doesn't appear to.

(Update) I also think I tried variations on $_.Exception.Response though may have gotten it wrong.

Getting just a response code seems like such a simple thing to do.


Solution

  • Here's an example, though it does a couple more things to allow you to test redirections as well as expected exceptions.

    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"