Private/GetHttpRequestWithCookie.ps1

. "$PSScriptRoot/Constants.ps1";
. "$PSScriptRoot/Models/HttpException.ps1";

# Make a get request to a $url while forcing the instance using the ARRAfinity cookie with $instanceGuid
function GetHttpRequestWithCookie(
    [Parameter(Mandatory=$True)]
    [string]$defaultHostName,
    [Parameter(Mandatory=$True)]
    [string]$url,
    [Parameter(Mandatory=$True)]
    [System.TimeSpan]$requestTimeOut,
    [Parameter(Mandatory=$False)]
    [string]$instanceGuid,
    [Parameter(Mandatory=$False)]
    [Boolean]$logRequest = $True) {

    $timeOutSeconds = $requestTimeOut.TotalSeconds;
    if ($timeOutSeconds -lt 1) { throw "requestTimeOut requires to be at least 1 second or more." }

    $session = New-Object Microsoft.PowerShell.Commands.WebRequestSession;
    $requestMessage = "Requesting $url";

    if (![string]::IsNullOrEmpty($instanceGuid)){
        $requestMessage = "$requestMessage for instance $instanceGuid";
        $cookie = New-Object System.Net.Cookie;

        # To force the instance you can set a cookie named ARRAffinity, this is what Azure uses to assign an Instance by ID
        # The domain name has to be the domain of the url calling the instance preceded with a '.'
        $cookie.Name = "ARRAffinity";
        $cookie.Value = $instanceGuid;
        $cookie.Domain = ".$defaultHostName";
        $session.Cookies.Add($cookie);
    }

    if ($logRequest){ Write-Host $requestMessage; }
    $timeOutSeconds = $requestTimeOut.TotalSeconds;

    try {
        $httpResponse = Invoke-WebRequest -Uri $url -WebSession $session -TimeoutSec $timeOutSeconds;
        return $httpResponse;
    }
    # Use custom exception object so it can be mocked
    catch [System.Net.WebException] {

        $webException = [HttpException]::new();
        $webException.Message = "$_";
        if ($_.Exception -eq $null) { throw $_; }

        # Regular statusCodes
        $statusCode = $_.Exception.Response.StatusCode;
        $responseMessage = $_.Exception.Response.StatusDescription;

        # Special case TimeOut
        if ($webException.Message -eq $Constants.InvokeWebRequestTimeOutMessage)
        {
            $statusCode = 408;
            $responseMessage = "Request Timeout";
        }

        # Other Exceptions
        $webException.ResponseMessage = if ([System.String]::IsNullOrEmpty($responseMessage)) { $webException.Message } else { $responseMessage };
        $webException.ResponseCode = if ($statusCode -eq $null) { -1 } else { $statusCode };
        throw $webException;
    }
}