SendKeys Method in Powershell
PowerShell has no built-in functionality to emulate keystrokes.
Practically, you have two options: COM-Automation and Interop.
- 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.
- 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)!
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
}
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}'