Retry PowerShell Invoke-WebRequest

PowerShell
Fetching resources over the network isn’t always reliable. Timeouts and other connections issues are quite common, especially if the server is under stress. If you’re okay with the resource being temporarily unavailable, feel free to use the following retry script:

Function Req {
    Param(
        [Parameter(Mandatory=$True)]
        [hashtable]$Params,
        [int]$Retries = 1,
        [int]$SecondsDelay = 2
    )

    $Params.Add('UserAgent', 'SomeThingDistinguishableForTheLogs')

    $method = $Params['Method']
    $url = $Params['Uri']

    $cmd = { Write-Host "$method $url..." -NoNewline; Invoke-WebRequest @Params }

    $retryCount = 0
    $completed = $false
    $response = $null

    while (-not $completed) {
        try {
            $response = Invoke-Command $cmd -ArgumentList $Params
            if ($response.StatusCode -ne 200) {
                throw "Expecting reponse code 200, was: $($response.StatusCode)"
            }
            $completed = $true
        } catch {
            New-Item -ItemType Directory -Force -Path C:\logs\
            "$(Get-Date -Format G): Request to $url failed. $_" | Out-File -FilePath 'C:\logs\myscript.log' -Encoding utf8 -Append
            if ($retrycount -ge $Retries) {
                Write-Warning "Request to $url failed the maximum number of $retryCount times."
                throw
            } else {
                Write-Warning "Request to $url failed. Retrying in $SecondsDelay seconds."
                Start-Sleep $SecondsDelay
                $retrycount++
            }
        }
    }

    Write-Host "OK ($($response.StatusCode))"
    return $response
}

An example how to use this function:

$req = Req -Params @{ 'Method'='GET';'Uri'='https://google.com/error404' }

The Req function takes three parameters:  a hashtable of request parameters (check splatting), number of times to retry and time in seconds between them. All the failed requests are logged to c:\logs\myscript.log for later analysis.