Skip to content

Instantly share code, notes, and snippets.

@markembling
Created September 15, 2009 13:56
Show Gist options
  • Star 42 You must be signed in to star a gist
  • Fork 25 You must be signed in to fork a gist
  • Save markembling/187305 to your computer and use it in GitHub Desktop.
Save markembling/187305 to your computer and use it in GitHub Desktop.
# SSH Agent Functions
# Mark Embling (http://www.markembling.info/)
#
# How to use:
# - Place this file into %USERPROFILE%\Documents\WindowsPowershell (or location of choice)
# - Import into your profile.ps1:
# e.g. ". (Resolve-Path ~/Documents/WindowsPowershell/ssh-agent-utils.ps1)" [without quotes]
# - Enjoy
#
# Note: ensure you have ssh and ssh-agent available on your path, from Git's Unix tools or Cygwin.
# Retrieve the current SSH agent PId (or zero). Can be used to determine if there
# is an agent already starting.
function Get-SshAgent() {
$agentPid = [Environment]::GetEnvironmentVariable("SSH_AGENT_PID", "User")
if ([int]$agentPid -eq 0) {
$agentPid = [Environment]::GetEnvironmentVariable("SSH_AGENT_PID", "Process")
}
if ([int]$agentPid -eq 0) {
0
} else {
# Make sure the process is actually running
$process = Get-Process -Id $agentPid -ErrorAction SilentlyContinue
if(($process -eq $null) -or ($process.ProcessName -ne "ssh-agent")) {
# It is not running (this is an error). Remove env vars and return 0 for no agent.
[Environment]::SetEnvironmentVariable("SSH_AGENT_PID", $null, "Process")
[Environment]::SetEnvironmentVariable("SSH_AGENT_PID", $null, "User")
[Environment]::SetEnvironmentVariable("SSH_AUTH_SOCK", $null, "Process")
[Environment]::SetEnvironmentVariable("SSH_AUTH_SOCK", $null, "User")
0
} else {
# It is running. Return the PID.
$agentPid
}
}
}
# Start the SSH agent.
function Start-SshAgent() {
# Start the agent and gather its feedback info
[string]$output = ssh-agent
$lines = $output.Split(";")
$agentPid = 0
foreach ($line in $lines) {
if (([string]$line).Trim() -match "(.+)=(.*)") {
# Set environment variables for user and current process.
[Environment]::SetEnvironmentVariable($matches[1], $matches[2], "Process")
[Environment]::SetEnvironmentVariable($matches[1], $matches[2], "User")
if ($matches[1] -eq "SSH_AGENT_PID") {
$agentPid = $matches[2]
}
}
}
# Show the agent's PID as expected.
Write-Host "SSH agent PID:", $agentPid
}
# Stop a running SSH agent
function Stop-SshAgent() {
[int]$agentPid = Get-SshAgent
if ([int]$agentPid -gt 0) {
# Stop agent process
$proc = Get-Process -Id $agentPid
if ($proc -ne $null) {
Stop-Process $agentPid
}
# Remove all enviroment variables
[Environment]::SetEnvironmentVariable("SSH_AGENT_PID", $null, "Process")
[Environment]::SetEnvironmentVariable("SSH_AGENT_PID", $null, "User")
[Environment]::SetEnvironmentVariable("SSH_AUTH_SOCK", $null, "Process")
[Environment]::SetEnvironmentVariable("SSH_AUTH_SOCK", $null, "User")
}
}
# Add a key to the SSH agent
function Add-SshKey() {
if ($args.Count -eq 0) {
# Add the default key (~/id_rsa)
ssh-add
} else {
foreach ($value in $args) {
ssh-add $value
}
}
}
# Start the agent if not already running; provide feedback
$agent = Get-SshAgent
if ($agent -eq 0) {
Write-Host "Starting SSH agent..."
Start-SshAgent # Start agent
Add-SshKey # Add my default key
} else {
Write-Host "SSH agent is running (PID $agent)"
}
@murdoch
Copy link

murdoch commented Aug 26, 2014

@krobe
Copy link

krobe commented Sep 22, 2014

@murdoch This is the code posh-git uses.

@iPoetDev
Copy link

iPoetDev commented Sep 13, 2020

@mark, @markembling

Powershell Core v7.1 Windows.

Starting SSH agent...
InvalidOperation: D:\OneDrive\Documents\PowerShell\SSH-Agent-Functions.ps1:45
Line |
45 | $lines = $output.Split(";")
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~
| You cannot call a method on a null-valued expression.

@iPoetDev
Copy link

In powershell 7.1 I was getting a

Powershell: You cannot call a method on a null-valued expression
on 45 | $lines = $output.Split(";")

So added to my solution: an If else and -eq on $null as $ouput / ssh-agent is null
[string]$output = ssh-agent

if ($output -eq $null) {

    $agentPid = 0

} else { 

@mavaddat
Copy link

mavaddat commented Feb 1, 2022

This functionality is now available in posh-sshell: https://github.com/dahlbyk/posh-sshell

@markembling
Copy link
Author

@mavaddat Yes it is 🙂 this is actually where that functionality first came from and you'll see I'm named in the readme there. I'd recommend using posh-sshell instead of this gist unless you have a good reason not to do so, but I'm keeping this gist up for reference and historical reasons.

@mavaddat
Copy link

mavaddat commented Feb 2, 2022

@markembling I saw that! Thank you for this. I may submit some PR's myself when I take a look at the inner workings. Cheers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment