Loosely Decoupled
GuideSSHPowerShell

How to Enable SSH on Windows Server 2022

Install the OpenSSH server with PowerShell, start sshd at boot, confirm the port 22 rule, and connect, plus where an administrator’s key really goes.

A patent-style drawing of a server cabinet with one empty bay, into which a relaxed man in a hoodie slides a new module. A small lamp on the module is the only cyan element.
On this page

TL;DR

In an elevated PowerShell session on the server:

PowerShell
Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0
Set-Service -Name sshd -StartupType Automatic
Start-Service -Name sshd
Get-NetFirewallRule -Name 'OpenSSH-Server-In-TCP' |
    Format-Table Name, Enabled, Direction, Action

Then from any machine with an SSH client:

Command
$ ssh Administrator@server-address

Sign in with the Windows account’s password. Key-based login for an administrator has one Windows-specific rule, covered under common failures.

Windows Server 2022 ships the OpenSSH server as an optional capability, not as an installed service. Adding it takes one command; the rest of the work is making sure it starts on boot and that the firewall lets the connection in. Everything below runs in a PowerShell session opened as Administrator.

Install the OpenSSH server capability

PowerShell
Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0

The four tildes are part of the name. The command downloads the capability from Windows Update, so the server needs a route to it, or a configured alternate source for features on demand.

Confirm it landed:

PowerShell
Get-WindowsCapability -Online | Where-Object Name -like 'OpenSSH*' |
    Format-Table Name, State

OpenSSH.Server should show Installed. If OpenSSH.Client shows NotPresent and you want it on the server too, add it the same way with OpenSSH.Client~~~~0.0.1.0.

The same install is available without a shell under Settings > Apps > Apps & features > Optional features > Add a feature, searching for “OpenSSH Server”. It is the same capability, so the commands that follow apply either way.

Start sshd and make it start at boot

The install registers the sshd service but doesn’t start it or set it to start at boot. Set the start type first, so a reboot before you finish does not leave the server unreachable:

PowerShell
Set-Service -Name sshd -StartupType Automatic
Start-Service -Name sshd
Get-Service -Name sshd

Status should read Running. The first start generates the host keys under C:\ProgramData\ssh\, which is also where sshd_config lives from now on.

Confirm the firewall rule

Installing the capability with Add-WindowsCapability normally creates and enables an inbound rule named OpenSSH-Server-In-TCP for port 22. Check rather than assume:

PowerShell
Get-NetFirewallRule -Name 'OpenSSH-Server-In-TCP' -ErrorAction SilentlyContinue |
    Format-Table Name, Enabled, Direction, Action

If the rule is missing, create it:

PowerShell
New-NetFirewallRule -Name 'OpenSSH-Server-In-TCP' -DisplayName 'OpenSSH Server (sshd)' `
    -Enabled True -Direction Inbound -Protocol TCP -Action Allow -LocalPort 22

Run it only when the check finds nothing. Rule names are unique, so New-NetFirewallRule fails if OpenSSH-Server-In-TCP already exists.

Connect from a client

From another machine, using its own OpenSSH client (macOS, Linux, and Windows 10 version 1809 or later all have one):

Command
$ ssh Administrator@server-address

Accept the host key on first connection and enter the account’s Windows password. Windows OpenSSH is a port of the same OpenSSH that ships on Linux and macOS, so the client and its keys behave the way you already expect. Authentication is the difference: sshd hands it to Windows. The default sshd_config has no AllowUsers or AllowGroups line, so any local or domain account Windows accepts can sign in. SSH keeps no user list of its own until you add one.

Expected result

You land in a cmd.exe prompt on the server. That’s the default shell for Windows OpenSSH, not a sign that something went wrong. To get PowerShell instead, set the default shell once on the server:

PowerShell
New-ItemProperty -Path 'HKLM:\SOFTWARE\OpenSSH' -Name DefaultShell `
    -PropertyType String -Force `
    -Value 'C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe'

Point it at pwsh.exe instead if PowerShell 7 is installed and that’s what you want to arrive in.

Common failures

Administrator gets Permission denied (publickey)

Error

Permission denied (publickey)

The key is in ~\.ssh\authorized_keys, and for any account in the local Administrators group Windows OpenSSH ignores that file entirely. The key has to be in C:\ProgramData\ssh\administrators_authorized_keys, and sshd refuses that file unless only SYSTEM and Administrators have access to it. The client is never told why; the reason goes to the server’s OpenSSH event log. The procedure, scripted, is in the article on key authentication for an administrator. Non-administrator accounts use ~\.ssh\authorized_keys as usual.

Connection refused or timing out

A stopped service usually gives a refusal. A missing firewall rule usually gives a timeout, because the firewall drops the packets. Get-Service sshd and the firewall check earlier tell you which. If both look right, confirm something is listening:

PowerShell
Get-NetTCPConnection -LocalPort 22 -State Listen

Add-WindowsCapability fails with 0x800f0954

The server can’t reach Windows Update, or can’t find the source. The usual cause is WSUS: Server 2022 can’t install OpenSSH from WSUS at all. One fix is the Group Policy setting Specify settings for optional component installation and component repair, under Computer Configuration > Administrative Templates

System. Enable it and select Download repair content and optional features directly from Windows Update instead of Windows Server Update Services. The other is to mount the Server 2022 Features on Demand ISO and pass its drive to -Source. The same fix applies to 0x800F0950 and the 0x8024xxxx connection errors.

ssh hangs after the password

Every command works, but the session never opens. Check Event Viewer under Applications and Services Logs > OpenSSH > Operational, which records each sign-in and refusal. Don’t wait for the Admin channel: it stays empty even when sshd can’t start. For that case, sshd -t names the broken line in sshd_config, and prints nothing when the file is valid.

Tested with

OS
Windows Server 2022 Datacenter (build 20348.5622)
OpenSSH
8.1p1 server, from the OpenSSH.Server capability
Client
OpenSSH on macOS 27
Date
October 2026

New articles, by email.

A short note when something new is published.