Powershell – Enable native OpenSSH Server in Windows 2019 and later

OpenSSH is the open-source version of the Secure Shell (SSH) tools used by administrators of Linux and other non-Windows for cross-platform management of remote systems. OpenSSH has been added to Windows (as of autumn 2018), and is included in Windows 10 and Windows Server 2019.

OpenSSH is a connectivity tool for remote login that uses the SSH protocol. It encrypts all traffic between client and server to eliminate eavesdropping, connection hijacking, and other attacks.

OpenSSH can be used to connect Window 10 (build 1809 and later) or Windows Server 2019 devices with OpenSSH Client installed to those devices with OpenSSH Server installed.

Manually enabling OpenSSH in Windows is quite an effort and if you want to do it for all your server you’d better automate this task.

The following powershell script enables OpenSSH in Windows 2019 and later. It also takes care on the necessary firewall port 22.

Please do not copy&paste and execute the script blindly. You have to adjust the value of the variable $content line 25 (!!!) and enter your own SSH public key.
Otherwise I would have access to your servers 🙂

Import-Module -Name 'NetSecurity'

# Setup windows update service to manual
$wuauserv = Get-WmiObject Win32_Service -Filter "Name = 'wuauserv'"
$wuauserv_starttype = $wuauserv.StartMode
Set-Service wuauserv -StartupType Manual

# Install OenSSH
Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0

# Set service to automatic and start
Set-Service sshd -StartupType Automatic
Start-Service sshd

# Setup windows update service to original
Set-Service wuauserv -StartupType $wuauserv_starttype

# Configure PowerShell as the default shell
New-ItemProperty -Path "HKLM:\SOFTWARE\OpenSSH" -Name DefaultShell -Value "$Env:SystemRoot\System32\WindowsPowerShell\v1.0\powershell.exe" -PropertyType String -Force

# Restart the service
Restart-Service sshd

# Configure SSH public key
$content = @"
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDTbhJ03NGgnGsk2T7HU/+0FbwjWcb/qwyxWyZpHAHJ+nWpqG0DA0IqKDbQeW/E1BApoLStlRWax35Z0WE4srNr7dPjOc3jWSoGLCrgnFbvFGBaqxrNA+QAhMFrMaoC5iHhpCZPF99afJEoZTf/3VhkNMPvhUpfThFIF0+3tJDko/Qe5/Dx64RWHe0/yNsq9/bOE5K2JmpTz+5Y9PwvrtmZcx7PwRyjllDsvjvKQG7Z7/inhQ8ff1HYkh1UtknV+T8e2te4WiYJJABWiLUeLh/2YgMnMoZJF6E+pcZLMASJU5WAWfmDQ6wiZtWUxk40uycJ01vfROW0ne2YsWiaZ31r root
"@ 

# Write public key to file
$content | Set-Content -Path "$Env:ProgramData\ssh\administrators_authorized_keys"

# set acl on administrators_authorized_keys
$admins = ([System.Security.Principal.SecurityIdentifier]'S-1-5-32-544').Translate( [System.Security.Principal.NTAccount]).Value
$acl = Get-Acl $Env:ProgramData\ssh\administrators_authorized_keys
$acl.SetAccessRuleProtection($true, $false)
$administratorsRule = New-Object system.security.accesscontrol.filesystemaccessrule($admins,"FullControl","Allow")
$systemRule = New-Object system.security.accesscontrol.filesystemaccessrule("SYSTEM","FullControl","Allow")
$acl.SetAccessRule($administratorsRule)
$acl.SetAccessRule($systemRule)
$acl | Set-Acl

# Open firewall port 22
$FirewallParams = @{ 
  "DisplayName"       = 'OpenSSH SSH Server (sshd)' 
  "Direction"         = 'Inbound' 
  "Action"            = 'Allow' 
  "Protocol"          = 'TCP'
  "LocalPort"         = '22' 
  "Program"           = '%SystemRoot%\system32\OpenSSH\sshd.exe'
}
New-NetFirewallRule @FirewallParams