The Computer Oracle

SendKeys Method in Powershell

--------------------------------------------------
Hire the world's top talent on demand or became one of them at Toptal: https://topt.al/25cXVn
and get $2,000 discount on your first invoice
--------------------------------------------------

Music by Eric Matyas
https://www.soundimage.org
Track title: Romantic Lands Beckon

--

Chapters
00:00 Sendkeys Method In Powershell
00:28 Accepted Answer Score 28
02:04 Answer 2 Score 1
02:33 Answer 3 Score 0
03:03 Answer 4 Score 3
03:13 Thank you

--

Full question
https://superuser.com/questions/1249976/...

--

Content licensed under CC BY-SA
https://meta.stackexchange.com/help/lice...

--

Tags
#powershell #telnet

#avk47



ACCEPTED ANSWER

Score 28


PowerShell has no built-in functionality to emulate keystrokes.

Practically, you have two options: COM-Automation and Interop.

  1. SendKeys via COM

Like in VB(S) you can create a Shell-Object and SendKeys. Here is the PowerShell way to do it.

$wshell = New-Object -ComObject wscript.shell;
$wshell.SendKeys('a')

If you would like to send a keystroke to a window, you have to activate it first:

$wshell = New-Object -ComObject wscript.shell;
$wshell.AppActivate('title of the application window')
Sleep 1
$wshell.SendKeys('~')

Some keystrokes have special variables like ~ for RETURN. Here is a complete list.
After activating a window it's often necessary to wait a second until it becomes responsive, otherwise it'll send the key to the PowerShell window, or to nowhere. The scripting Host's SendKeys method can be unreliable, but luckily there is a better approach.

  1. SendKeys via Interop

Like in C#, you can use the SendWait method from the .NET Framework in PowerShell.

[void] [System.Reflection.Assembly]::LoadWithPartialName("'System.Windows.Forms")
[System.Windows.Forms.SendKeys]::SendWait("x")

If you want to activate a window, it can be done like this:

[void] [System.Reflection.Assembly]::LoadWithPartialName("'Microsoft.VisualBasic")
[Microsoft.VisualBasic.Interaction]::AppActivate("Internet Explorer - Windows")

To Sleep, you can use the Start-Sleep Cmdlet.

Regarding your original problem, I would suggest the following solution:

# Open a Telnet window
Start-Process telnet.exe -ArgumentList 10.84.10.85
# Run the keystrokes
Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.SendKeys]::SendWait('myPassword{ENTER}')
Start-Sleep 1
[System.Windows.Forms.SendKeys]::SendWait('7{ENTER}')
Start-Sleep 1
[System.Windows.Forms.SendKeys]::SendWait('1{ENTER}')
Start-Sleep 1
[System.Windows.Forms.SendKeys]::SendWait('{ENTER}')
Start-Sleep 1
[System.Windows.Forms.SendKeys]::SendWait('{ENTER}')
Start-Sleep 1
[System.Windows.Forms.SendKeys]::SendWait('Y{ENTER}')
Start-Sleep 1
[System.Windows.Forms.SendKeys]::SendWait('')

WARNING: Be extra careful if you're using this method to send a password because activating a different window between invoking AppActivate and invoking SendKeys will cause the password to be sent to that different window in plain text (e.g. your favorite messenger)!




ANSWER 2

Score 3


function Do-SendKeys {
    param (
        $SENDKEYS,
        $WINDOWTITLE
    )
    $wshell = New-Object -ComObject wscript.shell;
    IF ($WINDOWTITLE) {$wshell.AppActivate($WINDOWTITLE)}
    Sleep 1
    IF ($SENDKEYS) {$wshell.SendKeys($SENDKEYS)}
}
Do-SendKeys -WINDOWTITLE Print -SENDKEYS '{TAB}{TAB}'
Do-SendKeys -WINDOWTITLE Print
Do-SendKeys -SENDKEYS '%{f4}'



ANSWER 3

Score 1


I did some of modification in the script, I have a list of IP server which have the same password and I want to telnet the list automatically and sendKey for deactivate or activate the FTP server .

my script is :

  ## - List of IP
  $printers = get-content "C:\Dir2\servers.txt"

  foreach ($IPAddress in $printers){

   ## - Start Telnet Session:
     start-process C:\Windows\System32\telnet.exe -argumentlist $IPAddress

   ## - SendKey for each IP
     $obj = New-Object -com Wscript.Shell
     sleep -s 3
     $obj.SendKeys("MyPassword{ENTER}")
     sleep -s 3
     $obj.SendKeys("7{ENTER}")
     sleep -s 3
     $obj.SendKeys("1{ENTER}")
     sleep -s 3
     $obj.SendKeys("{ENTER}")
     sleep -s 3
     $obj.SendKeys("{ENTER}")
     sleep -s 3
     $obj.SendKeys("Y{ENTER}")
     sleep -s 3
     $obj.SendKeys("{ENTER}")
     sleep -s 3
     }



ANSWER 4

Score 0


Here's a function that will run SendKeys and clean up the COM object when it's done. It's not perfect, but it works.

The -Delay parameter gives you some time to switch focus to another application before it sends the keys.

function Send-Keystrokes ([string] $Keys, [int] $Delay = 0)
{
    try
    {
        Start-Sleep -Seconds $Delay
        $wshell = New-Object -ComObject WScript.Shell
        $wshell.SendKeys($Keys)
        Start-Sleep -Seconds 1
    }
    finally
    {
        try
        {
            [System.Runtime.InteropServices.Marshal]::ReleaseComObject([System.__ComObject]$wshell) | Out-Null
            [System.GC]::Collect()
            [System.GC]::WaitForPendingFinalizers()
        }
        catch { }
    }
}