How to Transfer SSH Keys to a Remote Server on Windows (Equivalent to ssh-copy-id)


2 views

If you're a Windows user working with SSH, you might have encountered the need to copy your public key to a remote server. On Unix-like systems, the ssh-copy-id command simplifies this process. However, Windows lacks a built-in equivalent, which can be frustrating for developers accustomed to Unix workflows.

Since Windows doesn't natively support ssh-copy-id, we need alternative methods. Popular tools like PuTTY, Pageant, and Kitty (a PuTTY alternative) are commonly used, but they don't provide a direct ssh-copy-id equivalent. Here's how to achieve the same result manually or with scripts.

If you're using PuTTY or Kitty, follow these steps:

  1. Generate your SSH key pair using PuTTYgen.
  2. Copy the public key from PuTTYgen.
  3. SSH into the remote server and append the public key to ~/.ssh/authorized_keys.

Example command (after SSH login):

echo "ssh-rsa AAAAB3NzaC1yc2EAAA...your_key_here" >> ~/.ssh/authorized_keys

For a more automated approach, you can use PowerShell to replicate ssh-copy-id functionality:

function ssh-copy-id {
    param (
        [string]$user,
        [string]$hostname,
        [string]$pubKeyPath = "$env:USERPROFILE\.ssh\id_rsa.pub"
    )
    if (-not (Test-Path $pubKeyPath)) {
        Write-Error "Public key file not found at $pubKeyPath"
        return
    }
    $pubKey = Get-Content $pubKeyPath
    ssh ${user}@${hostname} "mkdir -p ~/.ssh && chmod 700 ~/.ssh && echo '$pubKey' >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"
}

Usage example:

ssh-copy-id -user myuser -hostname myserver.com

If you have WSL installed, you can simply use the native ssh-copy-id command:

wsl ssh-copy-id user@hostname

This is often the simplest solution if you're already using WSL for development.

When copying SSH keys:

  • Always verify the server's fingerprint before transferring keys
  • Use strong passphrases for your private keys
  • Set proper permissions on the remote authorized_keys file (600)
  • Consider using ssh certificates for larger deployments

While Windows doesn't have a built-in ssh-copy-id equivalent, several effective methods exist. The PowerShell script provides a close approximation, while WSL offers the most Unix-like experience. Choose the method that best fits your workflow.


While Linux/Mac users enjoy the convenience of ssh-copy-id, Windows administrators often struggle with manual SSH key transfers. The core functionality we need is:

  1. Generate a new key pair (if none exists)
  2. Copy the public key to remote server's ~/.ssh/authorized_keys
  3. Set proper permissions (600 for keys, 700 for .ssh folder)

Since Windows 10 1809, you can use OpenSSH client commands:

# Generate keys (if needed)
ssh-keygen -t rsa -b 4096

# Manual copy (replace with your details)
type $env:USERPROFILE\.ssh\id_rsa.pub | ssh user@host "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"

For Pageant/Kitty users, convert and transfer keys using:

# Convert Putty .ppk to OpenSSH format
puttygen id_rsa.ppk -O private-openssh -o id_rsa

# PowerShell transfer script
$pubKey = Get-Content "$env:USERPROFILE\.ssh\id_rsa.pub"
$session = New-PSSession -HostName remote.server -UserName admin
Invoke-Command -Session $session -ScriptBlock {
    if (-not (Test-Path "~/.ssh")) { New-Item -Type Directory -Path "~/.ssh" }
    Add-Content -Path "~/.ssh/authoruthorized_keys" -Value $using:pubKey
    icacls "~/.ssh/authorized_keys" /inheritance:r /grant:r "$env:USERNAME:F"
}
  • WinSCP: GUI-based key management with drag-and-drop
  • Git Bash: Provides Linux-like environment including ssh-copy-id
  • Cygwin: Full Linux toolchain port including ssh utilities

Create a reusable ssh-copy-id.ps1 script:

param(
    [Parameter(Mandatory=$true)]
    [string]$RemoteHost,
    
    [string]$User = $(whoami),
    [string]$KeyPath = "$env:USERPROFILE\.ssh\id_rsa.pub"
)

if (-not (Test-Path $KeyPath)) {
    Write-Error "Public key not found at $KeyPath"
    exit 1
}

$pubKey = Get-Content $KeyPath
$sshCommand = @"
if [ ! -d ~/.ssh ]; then mkdir -p ~/.ssh; fi;
echo '$pubKey' >> ~/.ssh/authorized_keys;
chmod 700 ~/.ssh;
chmod 600 ~/.ssh/authorized_keys;
"@

Write-Host "Transferring key to $RemoteHost..."
ssh "${User}@${RemoteHost}" $sshCommand

Always verify:

  • SSH server fingerprint before first connection
  • Permissions on remote authorized_keys file (must be 600)
  • Private key never leaves your machine during this process