The ssh-copy-id command is useful for configuring a server to allow authentication with
a given set of SSH keys. Read more on the command here.
Windows comes with a built-in SSH client. It’s an optional feature, however, so it must be enabled before use. One missing component is ssh-copy-id. Many options exist that replicate its behavior, but I wanted something very simple that I could stash in my PowerShell profile.
Here’s what I created:
| # Basic replacement for ssh-copy-id | |
| function ssh-copy-id { | |
| [CmdletBinding(PositionalBinding = $false)] | |
| Param( | |
| # Connection details | |
| [Parameter(Mandatory = $true, Position = 0)] | |
| [string] | |
| $Connection, | |
| # Identity file | |
| [Parameter()] | |
| [string] | |
| $i, | |
| # Enable verbose output | |
| [switch] | |
| $v = $false | |
| ) | |
| try { | |
| # Check to see if an identity file was provided | |
| if ("" -eq $i) { | |
| # No identity file; test ssh-agent output | |
| $agentOutput = ssh-add -L | |
| if ($null -eq $agentOutput) { | |
| # If no SSH agent output, use the default identity file | |
| if ($v) { | |
| "Using identity file ~/.ssh/id_rsa.pub" | Write-Host | |
| } | |
| $identity = Get-Content "~/.ssh/id_rsa.pub" -ErrorAction Stop | |
| } | |
| else { | |
| # Use the output from the SSH agent | |
| if ($v) { | |
| "Using output from ssh-agent" | Write-Host | |
| } | |
| $identity = $agentOutput | |
| } | |
| } | |
| else { | |
| # Use the provided identity file | |
| # Use the public key file if not specified | |
| if (!$i.EndsWith(".pub")) { | |
| $i = "$i.pub" | |
| } | |
| if ($v) { | |
| "Using identity file $i" | Write-Host | |
| } | |
| $identity = Get-Content $i -ErrorAction Stop | |
| } | |
| # Append the identity information to the end of the authorized_keys file. | |
| # Note that this requires the ~/.ssh directory to exist | |
| $identity | ssh $Connection "cat >> ~/.ssh/authorized_keys" | |
| # Check to see if the operation was successful | |
| if ($LastExitCode -ne 0) { | |
| throw "Failed to copy identity to host." | |
| } | |
| "Copied identity to $Connection" | Write-Host | |
| } | |
| catch { | |
| "Could not copy ID." | Write-Error | |
| "Failed item: ${$_.Exception.ItemName}" | |
| "Exception: ${$_.Exception.Message}" | |
| } | |
| } |
To copy default credentials, either from the SSH agent or from ~/.ssh/id_rsa.pub, run:
ssh-copy-id user@host
To specify the identity file to copy, run:
ssh-copy-id -i ~/.ssh/identity_file.pub user@host
This fulfills the main functionality of ssh-copy-id, but it doesn’t handle most error cases or any extended options. As such, it’s not intended to replace the original tool, but instead to simply provide a shortcut for Windows users of the built-in SSH client.
For the best SSH functionality on Windows, I recommend using the SSH tools available in the Windows Subsystem for Linux.