Public/Tasks/Invoke-SitecoreUrlTask.ps1

Set-StrictMode -Version 2.0
Function Invoke-SitecoreUrlTask {
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingUserNameAndPassWordParams','')]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingPlainTextForPassword','')]
    [CmdletBinding(SupportsShouldProcess=$true)]
    param(
        [Parameter(Mandatory=$true)]
        [string]$SitecoreInstanceRoot,
        [Parameter(Mandatory=$true)]
        [string]$SitecoreActionPath,
        [Parameter(Mandatory=$true)]
        [string]$Username,
        [Parameter(Mandatory=$true)]
        [string]$Password
    )

    $actionPage = "$SitecoreInstanceRoot/$SitecoreActionPath"

    if($PSCmdlet.ShouldProcess("$actionPage", "Invoke-SitecoreUrlTask")) {

        function IsLoginPage {
            param($response)

            return $response.BaseResponse.ResponseUri.AbsolutePath.ToLower() -eq '/sitecore/login'
        }

        function TestStatusCode {
            param($response)

            if($response.StatusCode -ne 200) {
                throw "The request returned a non-200 status code [$($response.StatusCode)]"
            }
        }

        try {
            # Create initial session to get
            $session = $null

            # Attempt to hit the action page directly
            Write-TaskInfo -Message $actionPage -Tag "Requesting"
            $actionResponse = Invoke-WebRequest -uri $actionPage -SessionVariable session -UseBasicParsing
            TestStatusCode $actionResponse

            # Check if we are actually on that page... If login required Sitecore
            # redirects to login page but as a 200
            if(IsLoginPage $actionResponse) {
                # Populate login data
                Write-Verbose "Authenticating"
                $fields = @{}
                $actionResponse.InputFields.ForEach({
                    if($_.HasMember('Value')){
                        $fields[$_.Name] = $_.Value
                    }
                })

                # Set login info
                $fields.UserName = $Username
                $fields.Password = $Password

                # Send login request, this time will contain redirect to action page
                $actionResponse = Invoke-WebRequest -uri $actionResponse.BaseResponse.ResponseUri.OriginalString -WebSession $session -Method POST -Body $fields -UseBasicParsing
                TestStatusCode $actionResponse
                if(IsLoginPage $actionResponse) {
                    throw "Authentication failed. Check username and password"
                }
            }

            Write-TaskInfo -Message "Completed Request" -Tag "Success"
        }
        catch {
            Write-Error -Message ("Error requesting $actionPage" + ": $($_.Exception.Message)")
        }
    }
}