Skip to content

Instantly share code, notes, and snippets.

@fdcastel
Created October 29, 2025 07:16
Show Gist options
  • Select an option

  • Save fdcastel/9648325ae5be548d1664c5433fd6e9ae to your computer and use it in GitHub Desktop.

Select an option

Save fdcastel/9648325ae5be548d1664c5433fd6e9ae to your computer and use it in GitHub Desktop.
Install Windows OpenSSH server
#
# Install Windows OpenSSH server
# https://learn.microsoft.com/en-us/windows-server/administration/openssh/openssh_install_firstuse
#
Add-WindowsCapability -Online -Name OpenSSH.Client~~~~0.0.1.0 # NOP in Server 2025 (already installed)
Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0 # NOP in Server 2025 (already installed)
Start-Service sshd
Set-Service -Name sshd -StartupType 'Automatic'
# Confirm the Firewall rule is configured. It should be created automatically by setup.
if (!(Get-NetFirewallRule -Name "OpenSSH-Server-In-TCP" -ErrorAction SilentlyContinue)) {
Write-Output "Firewall Rule 'OpenSSH-Server-In-TCP' does not exist, creating it..."
New-NetFirewallRule -Name 'OpenSSH-Server-In-TCP' -DisplayName 'OpenSSH Server (sshd)' -Enabled True -Direction Inbound -Protocol TCP -Action Allow -LocalPort 22
}
#
# [ON SERVER] Set OpenSSH shell to Powershell (Classic)
# https://learn.microsoft.com/en-us/windows-server/administration/OpenSSH/openssh-server-configuration#configuring-the-default-shell-for-openssh-in-windows
#
$NewItemPropertyParams = @{
Path = "HKLM:\SOFTWARE\OpenSSH"
Name = "DefaultShell"
Value = "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe"
PropertyType = "String"
Force = $true
}
New-ItemProperty @NewItemPropertyParams
#
# [ON CLIENT] Deploy the public key for administrators -- [using Powershell as OpenSSH shell]
# https://learn.microsoft.com/en-us/windows-server/administration/openssh/openssh_keymanagement#deploy-the-public-key
#
$sshTarget = 'administrator@SERVER_NAME'
$authorizedKeyFile = "$env:USERPROFILE\.ssh\id_ed25519.pub"
$authorizedKey = Get-Content -Path $authorizedKeyFile
ssh $sshTarget @"
Add-Content -Force -Path `$env:ProgramData\ssh\administrators_authorized_keys -Value '$authorizedKey' ; icacls.exe "`$env:ProgramData\ssh\administrators_authorized_keys" /inheritance:r /grant "Administrators:F" /grant "SYSTEM:F"
"@
#
# [ON SERVER] Restore default OpenSSH shell (cmd.exe)
#
Remove-ItemProperty -Path "HKLM:\SOFTWARE\OpenSSH" -Name DefaultShell -Force
#
# [ON CLIENT] Deploy the public key for administrators -- [using CMD as OpenSSH shell]
# https://learn.microsoft.com/en-us/windows-server/administration/openssh/openssh_keymanagement#deploy-the-public-key
#
$sshTarget = 'administrator@SERVER_NAME'
$authorizedKeyFile = "$env:USERPROFILE\.ssh\id_ed25519.pub"
$authorizedKey = Get-Content -Path $authorizedKeyFile
ssh $sshTarget @"
powershell.exe Add-Content -Force -Path `$env:ProgramData\ssh\administrators_authorized_keys -Value '$authorizedKey' ; icacls.exe "`$env:ProgramData\ssh\administrators_authorized_keys" /inheritance:r /grant "Administrators:F" /grant "SYSTEM:F"
"@
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment