GetAsyncKeyState or KeyAvailable in PsRemote session

Welcome Forums General PowerShell Q&A GetAsyncKeyState or KeyAvailable in PsRemote session

This topic contains 1 reply, has 2 voices, and was last updated by

 
Keymaster
1 year, 11 months ago.

  • Author
    Posts
  • #61659

    Participant
    Points: 0
    Rank: Member

    Hi

    I wrote a function that check if you are pressing or pressed Ctrl-Q from the last time the function run and if so exit the script

    This is useful for example if you have a long loop and you want to have the option to stop it by pressing a key but unlike Ctrl-C do it in a controlled position at the end of the loop

    So you can click Ctrl-Q, the loop will continue as normal until the end of the current loop and then stop

    I used the [console]/$Host methods KeyAvailable and ReadKey() and it's working grate but not in Powershell ISE
    so I fund a workaround for ISE by using GetAsyncKeyState() instead in it

    But the problem now is that if I Enter-PSSession this two solutions not working in there, GetAsyncKeyState() always return 0 and ReadKey return "Cannot see if a key has been pressed when either application does not have a console or when console input has been redirected from a file. Try Console.In.Peek."

    function Stop-IfKey
    {
        
        [CmdletBinding()]
        param
        (
            [Parameter(Mandatory=$false, Position=0)]
            [Switch]
            $InitializeIse
        )
        if ($InitializeIse)
        {
            if (!('Win32Functions.Win32GetAsyncKeyState' -as [type]))
            {
                $Signature = '[DllImport("user32.dll")]public static extern short GetAsyncKeyState(int vKey);'
                Add-Type -MemberDefinition $Signature -Name 'Win32GetAsyncKeyState' -Namespace Win32Functions
                Add-Type -AssemblyName System.Windows.Forms
            }
            $null = [Win32Functions.Win32GetAsyncKeyState]::GetAsyncKeyState([Windows.Forms.Keys]::LControlKey)
            $null = [Win32Functions.Win32GetAsyncKeyState]::GetAsyncKeyState([Windows.Forms.Keys]::RControlKey)
            $null = [Win32Functions.Win32GetAsyncKeyState]::GetAsyncKeyState([Windows.Forms.Keys]::Q)
            Return
        }
        
        $QuittingMassage = 'Quitting, user pressed control Q...'
        if ($Host.Name -notin 'Windows PowerShell ISE Host')
        {
            #[console]::TreatControlCAsInput = $true # For Ctrl-C
            if ([console]::KeyAvailable) # Or ($Host.UI.RawUI.KeyAvailable)
            {
                $key = [console]::readkey($true) # Or $key = $Host.UI.RawUI.ReadKey()
                if (($key.modifiers -band 'control') -and ($key.key -eq 'Q'))
                {
                    #Write-Warning -Message $QuittingMassage
                    #Exit
                    throw $QuittingMassage
                }
            }
        }
        else
        {
            if (([Win32Functions.Win32GetAsyncKeyState]::GetAsyncKeyState([Windows.Forms.Keys]::LControlKey) -or [Win32Functions.Win32GetAsyncKeyState]::GetAsyncKeyState([Windows.Forms.Keys]::RControlKey)) -and [Win32Functions.Win32GetAsyncKeyState]::GetAsyncKeyState([Windows.Forms.Keys]::Q))
            {
                #Write-Warning -Message $QuittingMassage
                #Exit
                throw $QuittingMassage
            }
        }
    }
    Stop-IfKey -InitializeIse
    
    $collection = @(1..5)
    foreach ($item in $collection)
    {
        'Loop {0}' -f $item
        Start-Sleep -Seconds 5 # Do stuff
        Stop-IfKey
    }
    'End'
  • #61954

    Keymaster
    Points: 1,704
    Helping HandTeam Member
    Rank: Community Hero

    You're not going to be able to duplicate this. PSSessions aren't like a Telnet or SSH session; you're still typing in your local console until you hit Enter, at which point the remote process runs. There's no "console connection" per se.

The topic ‘GetAsyncKeyState or KeyAvailable in PsRemote session’ is closed to new replies.