Skip to content

Instantly share code, notes, and snippets.

@1x24
Last active May 1, 2023 13:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save 1x24/508281c053c12b87b21f9ab8f80abe0d to your computer and use it in GitHub Desktop.
Save 1x24/508281c053c12b87b21f9ab8f80abe0d to your computer and use it in GitHub Desktop.
Windows 10/11 PowerShell Script to create and add SSH keys to a Linux server
#############################################################################################################################################################
#############################################################################################################################################################
# https://github.com/1x24
# 1x24 AT tuta.io
# March 31, 2023
#############################################################################################################################################################
# This PowerShell script checks if you have SSH keys on your Windows 10 or Windows 11 machine.
# If you do not have the SSH keys, it generates a modern one for you.
# In either case, it copies the key to your server and makes some configuration changes to make it easy to login with the keys.
# Save then use as follows:
# (1) In Windows Explorer, open the folder where this script use_ssh_keys.ps1 is saved
# (2) Press Shift+F10 and choose "Open Powershell window here". This is the easiest way.
# Don't have function keys? Then you can `Shift + Right-click` and select "Open Powershell window here".
# Note that in some versions of Windows, after that Shift+Right click you need to select
# "Show more options" before you can launch PowerShell from there.
# (3) Inside the Powershell window run the script as follows, substituting in your server username (to replace USERNAME), server host (to replace MY.SERVER.HOST)
# and the server port to replace SERVER_SSH_PORT (unless told otherwise, use the number 22)
# PowerShell -ExecutionPolicy Bypass -file .\use_ssh_keys.ps1 -Username USERNAME -ServerHost MY.SERVER.HOST -ServerPort SERVER_SSH_PORT
# (4) The script is going to ask you for a passphrase. You may simply press enter here.
# N.B. The passphrase secures your new key, but if you forget the password the key becomes unusable. I recommend pressing enter here. Do it twice.
# (5) Now the script will ask you for your SSH password. Enter the password as requested, and the script will finish its process.
# (6) From now on you can simply open PowerShell (see step 2) and run ssh MY.SERVER.HOST (no need for PuTTY or plink.exe) e.g. ssh fancy.server.com
#############################################################################################################################################################
#############################################################################################################################################################
param (
[Parameter(Mandatory=$true)] [string] $Username,
[Parameter(Mandatory=$true)] [string] $ServerHost,
[Parameter(Mandatory=$true)] [int] $ServerPort
)
try {
$keysFound = $false
$homeDir = [Environment]::GetFolderPath('UserProfile')
$sshDir = Join-Path $homeDir ".ssh"
# Default key type and path
$keyType = "ed25519"
$keyPath = Join-Path $sshDir "id_$keyType.pub"
$keyPathNoPub = Join-Path $sshDir "id_$keyType"
# Check for existing keys in the common locations
foreach ($potentialKeyType in @("rsa")) {
$potentialKeyPath = Join-Path $sshDir "id_$potentialKeyType.pub"
$potentialKeyPathNoPub = Join-Path $sshDir "id_$potentialKeyType"
if (Test-Path $potentialKeyPath) {
$keysFound = $true
$keyType = $potentialKeyType
$keyPath = $potentialKeyPath
$keyPathNoPub = $potentialKeyPathNoPub
break
}
}
# Generate a new SSH key if none are found
if (-not $keysFound) {
Write-Host "No SSH keys found. Generating a new one..."
$keyType = "rsa"
$keyPathNoPub = Join-Path $sshDir "id_$keyType"
$keyPath = $keyPathNoPub + ".pub"
ssh-keygen -o -t ed25519 -f $keyPathNoPub -q
}
# Copy the key to the remote server
Write-Host "Copying SSH key to the remote server..."
$sshCommands = "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"
type $keyPath | ssh -o StrictHostKeyChecking=no -o PreferredAuthentications=password -o PubkeyAuthentication=no `"$Username@$ServerHost`" $sshCommands
# Append configuration to the local SSH config file
$sshConfig = Join-Path $sshDir "config"
Write-Host "Appending configuration to the local SSH config file..."
if (-not (Test-Path $sshConfig)) {
New-Item -ItemType File -Path $sshConfig -Force | Out-Null
}
@"
Host $ServerHost
Hostname $ServerHost
User $Username
Port $ServerPort
IdentityFile $($keyPath -replace ".pub$","")
PreferredAuthentications publickey
GSSAPIAuthentication no
ChallengeResponseAuthentication no
HashKnownHosts no
KbdInteractiveAuthentication no
TCPKeepAlive yes
ServerAliveInterval 25
ServerAliveCountMax 600
"@ | Add-Content -Path $sshConfig
Write-Host "Done! Press any key to exit."
$host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") | Out-Null
}
catch {
Write-Host "Error: $($_.Exception.Message)"
Write-Host "Press any key to exit."
$host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") | Out-Null
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment