Automatically start Pageant with private keys in Windows

Saturday, November 26, 2011

First some background. Pageant is a SSH authentication agent for most of the tools (plink, putty, pscp, and psftp) from the PuTTY familiy. It does it job by holding your private keys and provide it to one of these tools when they need to authenticate with a remote server. The only problem I have with it, is that you need to start pageant manually each time you logon at your account. Even worse you have to add the private keys you want to be loaded by the agent. So after a couple of times I began to wonder if I should be automating this.

After a couple of times more I started to script this with PowerShell. The script takes a single directory (or single ppk file) and loads all private keys (*.ppk) found in the directory or child directories.

You can download the file loadppks.ps1 here (save as *.ps1).

# -----------------------------------------------------------------------------
# PowerShell script for loading your private key files with pageant.exe
# Author: Martijn Burgers
# Find me on Twitter: http://www.twitter.com/martijnburgers
# -----------------------------------------------------------------------------
$usage = "Usage: loadppks.ps1 [Dir|ppk file]";

if ($args.Count -eq 0) {
 write-host "No arguments supplied!" 
 write-host $usage
 exit
}

if ($args.Count -gt 1) {
 write-host "To many arguments supplied!" 
 write-host $usage
 exit
}

#declare list of ppk files
$files = New-Object 'System.Collections.Generic.List[string]'

#check if arg[0] is a directory
$isDirectory = Test-Path $args[0] -pathType container

if ($isDirectory -eq $true) {
	
	write-host "Searching for *.ppk in" $args[0] "and al sub directories"
	$List = get-childitem $args[0] -recurse | where {$_.extension -eq ".ppk"}

	foreach ($item in $List)  {   
		$files.Add($item.fullname)
	}
} 
else 
{
	#so must be a file then. Check if it exists.
	if([IO.File]::Exists($args[0]) -eq $true) {
		$files.Add($args[0])
	} else {
		write-host "The given file does not exists!"
		write-host $usage
		exit
	}
}

$tool = "pageant.exe"
write-host "Starting pageant with private keys"
#call pageant with ppk files
&$tool $files.ToArray()
# -----------------------------------------------------------------------------

The last thing will be executing this script after you logon to your account. This can be done in a variety of ways and I thought this step was the most simple one but it got me into a better understanding on how processes can be run on a windows machine with User Account Control (UAC) enabled. Normally I would choose to create a logon script which can be set via the local group policy editor (gpedit.msc) but I noticed some strange behaviour in the started pageant process. The thing is that because my user and probably your as well is part of the Administrator group which will run the powershell script with elevated rights. This will also start the pageant process with elevated rights and without UAC virtualization. Now when you use tools which utilize the pageant process (i.e plink, putty, etc) and which are not run with elevated rights or run with UAC virtualization enabled you get the following error:

 

 

And this is strange because you actually see the pageant process running in your task manager. So what's going on? This is because when you login as a administrator, Windows 7 gives you two tokens: a standard user access token and a administrator access token. The first one is used to start explorer.exe and is the parent for a lot of processes which will by default also use this token. Only when you run the program as a administrator the second token will be used after you granted additional rights prompted by the UAC. So there a a couple of ways to get it to work: first you could disable the UAC or second you could run all the tools which need pageant to run with elevated rights as well. With both solutions I don't feel satisfied thus that is not what I'am going to do. I tried to find a solution to run the logon script without the elevated rights but I don't think it's possible. Also keep in mind that when you're not part of the Administrators group you have no problems with this solution!

For the sake of completeness I will let the logon script as a local group policy to be part of this post even though I ain't using it. The reason for this is that it could be the better solution for your situation but keep in mind what I just described. Scroll down for the solution I am using.

Starting script via a group policy

 

Start Group Policy Editor via Windows Run (WINKEY + R)

 

image_thumb1

 

Go to User Configuration > Windows Settings > Scripts (Logon/Logoff) > Loggon

 

image_thumb5

 

Click on the Add button of the PowerShell Scripts tab.

 

image_thumb7

 

Browse the location of the script and provide the right script parameter. For example the directory where your private keys are located.

 

image_thumb9

Click OK twice.

 

image_thumb11

Starting script via a batch file in startup folder

Create a batch file in your Windows startup folder (C:\Users\<username>\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup) and add the following content to it.

powershell d:\dev\utils\loadppks.ps1 'directory with your keys'

 

Test it by logging off and logon back into your account and check your system tray. Pageant (bottom right) is loaded.

 

image_thumb

 

[UPDATE]

Starting script via Task Scheduler

Create a Task with the Task Scheduler that comes with Windows 7. Use the trigger "When I log on".

 

Comments (1) -

windows wallpapersUnited Stateswindows wallpapers said:

Excellent learn, I simply passed this onto a colleague who was doing a little analysis on that.

nice article….thanks

Comments are closed