Created
February 28, 2026 18:29
-
-
Save ankitg12/61628ccd21b8355f1ac9db509bf7f2ab to your computer and use it in GitHub Desktop.
Windows Powershell Script to Push SSH Keys Using plink
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <# | |
| .SYNOPSIS | |
| Push an SSH public key to a remote Linux host using PuTTY plink. | |
| .DESCRIPTION | |
| - Adds the given public key to ~/.ssh/authorized_keys | |
| - Avoids duplicates | |
| - Creates ~/.ssh if missing | |
| - Uses base64 encoding to safely transmit the key | |
| .EXAMPLE | |
| .\push-key.ps1 -Host example.com -User ubuntu | |
| .EXAMPLE | |
| .\push-key.ps1 -Host 192.168.1.10 -User root -Password mypass | |
| .EXAMPLE | |
| .\push-key.ps1 -Host server -KeyFile "$env:USERPROFILE\.ssh\id_ed25519.pub" | |
| #> | |
| [CmdletBinding()] | |
| param( | |
| [Parameter(Mandatory=$true)] | |
| [string]$Host, | |
| [Parameter()] | |
| [string]$User = "root", | |
| [Parameter()] | |
| [string]$Password, | |
| [Parameter()] | |
| [string]$KeyFile = "$env:USERPROFILE\.ssh\id_rsa.pub", | |
| [Parameter()] | |
| [string]$PlinkPath = "C:\Program Files\PuTTY\plink.exe", | |
| [Parameter()] | |
| [string]$HostKey = "*" | |
| ) | |
| Set-StrictMode -Version Latest | |
| $ErrorActionPreference = "Stop" | |
| # Validate inputs | |
| if (-not (Test-Path -LiteralPath $PlinkPath)) { | |
| throw "plink.exe not found at: $PlinkPath" | |
| } | |
| if (-not (Test-Path -LiteralPath $KeyFile)) { | |
| throw "Public key file not found: $KeyFile" | |
| } | |
| # Read public key | |
| $pubkey = (Get-Content -LiteralPath $KeyFile -Raw).Trim() | |
| if ([string]::IsNullOrWhiteSpace($pubkey)) { | |
| throw "Public key file is empty" | |
| } | |
| # Encode key to avoid shell quoting issues | |
| $pubkeyB64 = [Convert]::ToBase64String( | |
| [Text.Encoding]::UTF8.GetBytes($pubkey) | |
| ) | |
| # Remote script | |
| $remoteCmd = @" | |
| set -e | |
| umask 077 | |
| mkdir -p ~/.ssh | |
| chmod 700 ~/.ssh | |
| KEY=\$(printf '%s' '$pubkeyB64' | base64 -d 2>/dev/null || printf '%s' '$pubkeyB64' | base64 --decode) | |
| AUTH=~/.ssh/authorized_keys | |
| touch "\$AUTH" | |
| chmod 600 "\$AUTH" | |
| grep -qxF "\$KEY" "\$AUTH" 2>/dev/null || printf '%s\n' "\$KEY" >> "\$AUTH" | |
| echo KEY_PUSHED | |
| "@.Trim() | |
| # Build plink args | |
| $plinkArgs = @( | |
| "-ssh", | |
| "-batch", | |
| "-hostkey", $HostKey | |
| ) | |
| if ($Password) { | |
| $plinkArgs += @("-pw", $Password) | |
| } | |
| $plinkArgs += @( | |
| "$User@$Host", | |
| $remoteCmd | |
| ) | |
| # Execute | |
| & $PlinkPath @plinkArgs | |
| if ($LASTEXITCODE -ne 0) { | |
| throw "plink failed with exit code: $LASTEXITCODE" | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment