Skip to content

Mark Embling

Blog

SSH Agent in Powershell

Those of you using git will more than likely be pushing and pulling over a SSH connection (to github for example). Recently I posted about my preference for using git from within Powershell. However there was always one really annoying thing when compared to using git from my OS X and linux machines - the need to type my private key passphrase every single time I do a push or pull. It got to the point where I decided to do something about it. Enter ssh-agent.

What is SSH-Agent?

SSH-agent is a process which runs in the background and stores the private key and passphrase. This means that you do not have to repeatedly type it every time you need to use your key. Instead you just provide it once, when the ssh-agent process is started. Users of Putty may be familiar with Pageant, which serves the exact same purpose.

So What's The Problem?

Unfortunately, ssh-agent seems to have been designed with Bash and other unix shells in mind. It has a very strange way of working. When the agent is started, it emits some information about itself (process ID etc) which should be placed into environment variables, and sits in the background. Instances of the SSH client can then refer to these variables and interface with the running agent process for obtaining key details. The problem with this approach is that the output provided by ssh-agent is not compatible with Powershell or Command.exe.

Make It So!

In order to get around this problem, I have written a Powershell script which provides several functions for starting and managing ssh-agent. It takes the output of the program and sets the appropriate environment variables through Powershell's .NET methods.

The script can be found in a gist I have created on github. To make use of it, simply place into your powershell profile folder at %USERPROFILE%\Documents\WindowsPowershell or any other location of your choice and then include it in your main profile.ps1 file (or a blank one if you have not already created one).

. (Resolve-Path ~/Documents/WindowsPowershell/ssh-agent-utils.ps1)

As you can see, there are several functions in the file:

  • Get-SshAgent - Returns the process ID of the running agent, or zero if there is not one currently running.
  • Start-SshAgent - Starts the agent process and sets the appropriate environment variables for SSH.
  • Stop-SshAgent - Stops the process if there is one and unsets the variables.
  • Add-SshKey - Instructs the agent to add the given key to itself. This will cause you to be prompted for the passphrase.

The final section of the file is run automatically when you open a new Powershell window. It will check for an agent process and if none is found it will begin one and add your default key (normally ~/.ssh/id_rsa). Change this to pass in an alternative key path if necessary, although these defaults will probably fit most people's needs. If an agent is found, a message is displayed to show that this is the case. Since ssh-agent is always running in the background, using this solution will cause you to receive only one prompt for the key passphrase - when the first Powershell window is opened. If you later need to close ssh-agent (maybe you wish to let someone else use your computer), simply invoke Stop-SshAgent.

Notes

I have made it run and add the default key automatically as I use git regularly and if I am opening Powershell, I am almost certainly going to be using git or SSHing into something sooner or later. It is also for this reason that I find this such a useful solution - I do not like having to type my key passphrase, but equally I understand the security benefits having a passphrase (as opposed to a blank one) brings.

In order for this script to work correctly, the binaries for ssh and ssh-agent must be accessible on the PATH. If you have installed Msysgit to allow use from the windows command line (I always do this), this will most likely be set for you already. If not, they will be located in the bin folder within your git installation.

I created this and wrote this post because I could find nothing for using ssh-agent on Windows at all, let alone Powershell. I find this surprising as its such a useful thing to have. However I did learn a lot about ssh-agent in the process, so its no loss at all. I hope this saves somebody some time since now the wheel will not need to be re-invented.

Return to blog