SSH Plus for Windows (SSH.exe with Password Functionality)

Carrying on from How to Pass a Password (and Enter press) to a Prompt in Powershell, I wrote this little module that I call ‘SSH Plus for Windows’. Copy and paste the script below into a text editor, and save as say SSH_PLUS.psm1. Then to use it, follow the example below:

PS> import-module C:\SCRIPTS\SSH_PLUS.psm1
PS> SSHplus-pass
Password: *********
PS> ssh+ admin@10.9.1.0 node show local

The function SSHplus-pass supplies a password (which is stored in a global variable for as long as the PowerShell window stays open). There are also functions SSHplus-path which allows setting a path for the temporary PS1 file we create, and SSHplus-timeout which allows you to tune the timeout from the default 4 seconds. Instead of Windows SSH.exe (or SSH), run SSH+ - simples!

Note 1: If you’ve never connected to the host before, you will need to cache the SSL key. Use ssh.exe for this.
Note 2: If nothing’s happening, could be that ssh.exe / rssh.exe is still running in the background, kill that and all should be good again.

Image: SSH+ in action (ignore the warning about verbs)

The Script / Module


#############
## SSHplus ##
#############

Function SSHplus-pass{
  Param([String]$Password)
  If(!$Password){$Global:SecPW = Read-Host "Password" -AsSecureString}
  Else{$Global:SecPW = $Password | ConvertTo-SecureString -AsPlainText -Force}
}

Function SSHplus-path{
  Param([String]$TempFolderPath)
  If(!$TempFolderPath){$TempFolderPath = Read-Host "Path for SSHplus Temp File"}
  If(!(Test-Path ($TempFolderPath))){"Invalid path!";RETURN}
  $Global:TmpFolderPath = $TempFolderPath
}

Function SSHplus-timeout{Param([Int]$Global:SSHtimeout = 4)}

Function SSH+{
  ## CHECK: PW / TEMP FILE PATH / TIMEOUT ##
  If(!$Global:SecPW){"Use SSHplus-pass to enter password.";RETURN}
  If(!$Global:TmpFolderPath){$Global:TmpFolderPath = $Pwd}
  [String]$TempFilePath = Join-Path $Global:TmpFolderPath "SSH+_Temp.ps1"
  "TEST" | Set-Content $TempFilePath
  If(!(Test-Path $TempFilePath)){
    [String]("Cannot write to " + $Global:TmpFolderPath + ". Use SSHplus-path to enter path of SSH+ Temp File.")
    RETURN
  }
  If(!$Global:SSHtimeout){$Global:SSHtimeout = 4}
 
  ## OBTAIN VARIABLES FROM ARGS ##
  # ARGs are expected as: ssh+ user@host command ...
  [String]$UserAtDest = $Args[0]
  [String]$Dest = ($Args[0].Split("@"))[0]
  $Args[0] = ""
  [String]$Command = ""
  $Args | Foreach{ $Command += ($_ + " ") }
  $Command = $Command.Trim(" ")
 
  ## MAX THE SHELL BUFFERS AND SET THE TITLE ##
  $Window = (Get-Host).UI.RawUI
  $resize = $Window.BufferSize
  $resize.Height = 9999
  $resize.Width = 9999
  $Window.BufferSize = $resize
  $host.ui.RawUI.WindowTitle = "Windows PowerShell w SSH+"
 
  ## PAINTEXT THE PASSWORD ##
  $BSTR = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($Global:SecPW)
  [String]$CTPW = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR)
 
  ## CREATE THE TEMP PS FILE (this PS1 activates after the SSH command) ##
  If(Test-Path $TempFilePath){Remove-Item -Path $TempFilePath}
  [System.Array]$Temp = @()
  $Temp += ('Sleep ' + "$Global:SSHtimeout")
  $Temp += ('$wshell = New-Object -ComObject wscript.shell')
  $Temp += ('$wshell.AppActivate("Windows PowerShell w SSH+")')
  $Temp += ('$wshell.SendKeys("' + $CTPW + '")')
  $Temp += ('$wshell.SendKeys("~")')
  $Temp += ('Remove-Item -path "' + $TempFilePath + '"')
  $Temp | Set-Content $TempFilePath
 
  ## ACTIVATE SSH+_Temp.ps1 ##
  start powershell.exe '.\SSH+_Temp.ps1' -WorkingDirectory $Global:TmpFolderPath
  ssh.exe $UserAtDest $Command
}

Comments