Invoke-WebRequest, a First Attempt

“To learn PowerShell, you first have to have a problem to solve.”

Well, this is utterly non-work-related, but I’m sure I can find more respectable uses than defeating the idleout of a web chat.

The situation is pretty simple: I’m on a fandom site where the web chat has an annoying ‘feature’ of disconnecting us after 15 minutes of idle time.  It is a site with some DB-based auth behind it (i.e. forms-based auth, not HTTP 401-based.)  The script below makes two calls to Invoke-WebRequest.

$response1 is from merely getting the page.

$repsonse2 is from submitting the login info.

$response 3 is the heartbeat string I send to the chat.  This one gets refreshed every 10 minutes.

 function Stop-ChatIdleTimeout
{
    param (
        $credentialCliXmlPath = "$home\gunslinger-girl.up-with.com-Credentials.clixml"
    );

    begin
    {
        function Write-WaitTime
        {
            Write-Progress (Get-Date) "Waiting for the 10 minute mark..."; 
        } # function Write-WaitTime
        
        function Start-Wait00Seconds
        { 
            while ((Get-Date -f 'ss') -ne '00') 
            { 
                Start-Sleep -Milliseconds 250; 
            } # while ((Get-Date -f 'ss') -ne '00') 
        } # function Start-Wait00Seconds
    
        $ErrorActionPreference = 'stop';

        $url = 'https://gunslinger-girl.up-with.com';
        $chatUrl = 'https://gunslinger-girl.up-with.com/chatbox/chatbox_actions.forum?archives';
        $path = "$home\gunslinger-girl.up-with.com-AntiIdle.txt";

        if (!(Test-Path -Path $credentialCliXmlPath))
        {
            Write-Warning "$($MyInvocation.MyCommand.Name) $credentialCliXmlPath not found.  Stopping";
            Write-Host "Create the file with the following command:";
            "Get-Credential | Export-Clixml '$credentialCliXmlPath'";
            return;
        } # if (!(Test-Path -Path $credentialCliXmlPath))

        if (!($credential = Import-Clixml $credentialCliXmlPath -ErrorAction SilentlyContinue))
        {
            Write-Warning "$($MyInvocation.MyCommand.Name) failed to import $credentialCliXmlPath.  Stopping";
            return;
        } # if (!($credential = Import-Clixml $credentialCliXmlPath -ErrorAction SilentlyContinue))

        if (
            !($username = $credential.UserName) -or
            !(
                $password = [System.Runtime.InteropServices.marshal]::PtrToStringAuto(
                    [System.Runtime.InteropServices.marshal]::SecureStringToBSTR($credential.Password)
                )
            )
        )
        {
            Write-Warning "$($MyInvocation.MyCommand.Name) failed to decrypt $credentialCliXmlPath.  Stopping";
            return;
        } # # if ( !($username ...

        notepad.exe $path;

        if (!($response01 = Invoke-WebRequest -Uri $url -SessionVariable sessionVariable))
        {
            Write-Warning "$($MyInvocation.MyCommand.Name) failed to connect to $url.  Stopping";
            return;
        } # if (!($response01 = Invoke-WebRequest -Uri $url -SessionVariable sessionVariable))

        $form = $response01.Forms[1];
        $form.Fields.username = $userName;
        $form.Fields.password = $password;

        if (!($response02 = Invoke-WebRequest -UseBasicParsing ($url + $form.Action) -WebSession $sessionVariable -Method Post -Body $form.Fields))
        {
            Write-Warning "$($MyInvocation.MyCommand.Name) failed to log in to $url.  Stopping";
            return;
        } # if (!($response02 = Invoke-WebRequest -UseBasicParsing ($url + $form.Action) ...

        Write-WaitTime;
        Start-Wait00Seconds;

        while((Get-Date -f 'mm') -notmatch '9$')
        {
            Write-WaitTime;
            start-sleep -Seconds 60; 
        } # while((Get-Date -f 'mm') -notmatch '9$') 
    
        start-sleep 5;
    
    } # begin

    process 
    {
        while (1)
        {
            if (!($heartbeat = Get-Content -ErrorAction SilentlyContinue -Path $Path)) { $heartbeat = '.'; }
            $heartbeat = "&mode=send&sent=$($heartbeat -replace '\s', '%20')&sbold=0&sitalic=0&sunderline=0&sstrike=0&scolor=#ffffff";
        
            Start-Wait00Seconds;
        
            if (!($response03 = Invoke-WebRequest -Body $heartbeat -Uri $chatUrl -WebSession $sessionVariable -Method Post))
            {
                Write-Warning "$($MyInvocation.MyCommand.Name) failed to connect to $url.  Stopping";
                return;
            } # if (!($response03 = Invoke-WebRequest -Body $heartbeat -Uri $chatUrl ...

            Write-WaitTime;
            start-sleep -Seconds 545;
    
        } # while (1)
    
    } # process

} # Stop-ChatIdleTimeout