Just in the last week, I’ve seen at least four people asking about SSH from PowerShell, and at least three of those specifically were looking for something they could script. That is, they needed a way to make an SSH connection, and then run commands on the remote PC and do switches in their script based on the output of those commands, so they could automate complicated server-side tasks.

Generally, the simplest answer to that is to write the scripts on the server, and then invoke them from PowerShell using the PLink executable which comes with Putty. However, that’s not very satisfactory, and it requires you to know a Linux scripting language like Perl or Python, and also requires you to have uploaded and tested that script ahead of time. Not always practical.

It’s also possible to do this using the NetCmdlets from /n and I’m constantly surprised at how unwilling people are to pay for them.

Well, I’ve already written my own little workaround using SharpSSH, a library I found on SourceForge from years ago, so I figured I’d share it with you. You might want to read the CodeProject Article about the first release of SharpSSH if you want more information about it, but otherwise, just download the binaries, extract them, and put the three dll’s somewhere handy. I keep mine in a “Libraries” folder within my WindowsPowerShell profile directory, so they’re easy to include in a backup of my scripts.

Now, lets say that your task is to ssh into a server, do a process check to see if anyone else is logged in, and if not, restart the server immediately, otherwise, schedule a reboot for midnight. Here’s the script for that:


New-SshSession jaykul huddledmasses.org ## You'll be prompted for a password
if( Invoke-Ssh who '\$'| select-string "^(?!jaykul).*pts/\d"  ) {
   Invoke-Ssh "shutdown -r 0:00"  '\$'
}
else {
   Invoke-Ssh "shutdown -r now"  '\$'
}
Remove-SshSession
 

Notice that I use \$ (backslash dollar-sign) as my “expect” text. That’s the last character on my prompt. It occasionally backfires, so you might want to use something more precise, in my case, I usually would store a patters for the full prompt (as a regular expression):

$prompt = '\[jaykul@peace.*\]\$'

Here’s the script module with the functions you’ll need. You can just dot-source it, or use it as a module in PowerShell 2. Hope this helps someone.

A footnote: There’s a lot more functionality in the SharpSSH module, including support for SCP and SFTP, but there’s also a few oddities, like the SshShell object exposing your password as a plain string property (which is why I made New-SshSession not return the object by default: when you specify -Passthru it will print the password property to the console if you don’t trap the output in a variable). Have fun, and feel free to expand on this module by pasting new versions to PoshCode!

Reblog this post [with Zemanta]

5 Responses to “Scriptable SSH from PowerShell”

  • Great one Joel! Will definitely be mentioning this in the next podcast.

  • Oisin G. says:

    Nice work man, really cool.

  • Tyson.Kopczynski says:

    Rock’en… If I have time, and if you do not mind. I will rip some of the SCP functionality out of a module I wrote for a client of mine and enhance this module.

  • Alan Renouf says:

    Great post, I was looking for a way to extract security information from an ESX server and this looks like it will do the trick. Thanks

  • Dan Baskette says:

    Very Nice. I tried out NetCMDLETS in my first version of my PowerVDI scripts and eventually settled on using PLINK. This seems to be an even cleaner way to do it for “free”. The problem I had with plink was it was really more of a command forwarder. I found I was building A LOT of SSH sessions that after awhile got very time consuming.

    Thanks for the post.