OpenSSH Server lets you securely run Command Prompt, PowerShell, and approved command-line tools on a Windows PC from another device over encrypted SSH. This procedure applies to Windows 11 and Windows 10 version 1809 (build 17763) or later. Install the built-in OpenSSH Server optional feature, start the sshd service, confirm the Windows Firewall rule for TCP port 22, and test a connection from a second device. For regular remote access, use a non-administrator account and then configure public-key authentication.

Prerequisites and compatibility​

Before starting, confirm the following:
  • You have a local account that belongs to the computer’s built-in Administrators group.
  • The target PC runs Windows 10 version 1809 or newer, or any supported Windows 11 release.
  • PowerShell is version 5.1 or later.
  • The PC is powered on, connected to the network, and not sleeping when you intend to connect.
  • You know the username and password for the account that will sign in remotely.
  • A second PC, Mac, Linux device, or SSH-capable terminal is available for testing.
Open Windows PowerShell as Administrator, then check the OS, PowerShell version, and administrative status:
Code:
winver
$PSVersionTable.PSVersion
(New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
Expected results:
  • winver shows Windows 10 version 1809 or later, or Windows 11.
  • PowerShell shows major version 5 and minor version 1 or later.
  • The last command returns True.
Warning: Enabling an SSH server creates a remote sign-in path to the PC. Do not forward TCP port 22 from your router to the internet unless you have deliberately restricted access, configured public-key authentication, and understand the exposure. For most home and office use, allow SSH only from the local network or a trusted VPN.

Primary procedure​

1. Check whether OpenSSH Server is already installed​

Open PowerShell as Administrator and run:
Get-WindowsCapability -Online | Where-Object Name -like 'OpenSSH*'
Look for this entry:
Code:
Name  : OpenSSH.Server~~~~0.0.1.0
State : Installed
If the state is Installed, skip to step 3. If it is NotPresent, install it by using either Settings or PowerShell.

2. Install OpenSSH Server​

Windows 11 Settings method​

  1. Open Start > Settings.
  2. Select System > Optional features.
  3. Under Add an optional feature, select View features.
  4. Search for OpenSSH Server.
  5. Select OpenSSH Server.
  6. Select Next > Add.
  7. Wait for the installation to finish.
You do not need to install OpenSSH Client on the server unless you also want that PC to initiate SSH connections to other systems.

Windows 10 Settings method​

  1. Open Start > Settings.
  2. Select Apps > Apps & features.
  3. Select Optional features or Manage optional features.
  4. Select Add a feature.
  5. Search for OpenSSH Server.
  6. Select OpenSSH Server > Install.
  7. Wait for installation to complete.

PowerShell method for Windows 10 or Windows 11​

Open PowerShell as Administrator and run:
Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0
Expected output includes:
Code:
Online        : True
RestartNeeded : False
A Windows restart is normally not required after this installation. If the command reports that a restart is required, restart before continuing.

3. Start OpenSSH Server and make it start automatically​

In elevated PowerShell, run:
Code:
Start-Service sshd
Set-Service -Name sshd -StartupType Automatic
Get-Service sshd
Expected result:
Code:
Status   Name   DisplayName
------   ----   -----------
Running  sshd   OpenSSH SSH Server
The automatic startup setting means the SSH server resumes after a normal Windows restart.
You can also manage the service in the graphical interface:
  1. Press Start and type services.msc.
  2. Open Services.
  3. Double-click OpenSSH SSH Server.
  4. Set Startup type to Automatic.
  5. Select Start if the service is not already running.
  6. Select OK.

4. Verify the firewall rule for SSH​

OpenSSH Server normally creates and enables an inbound Windows Defender Firewall rule named OpenSSH-Server-In-TCP. It allows inbound TCP connections on port 22.
Check it in elevated PowerShell:
Code:
Get-NetFirewallRule -Name OpenSSH-Server-In-TCP |
    Get-NetFirewallPortFilter |
    Format-Table Protocol, LocalPort
Expected result:
Code:
Protocol LocalPort
-------- ---------
TCP      22
If the rule does not exist, create it:
Code:
New-NetFirewallRule `
    -Name 'OpenSSH-Server-In-TCP' `
    -DisplayName 'OpenSSH Server (sshd)' `
    -Enabled True `
    -Direction Inbound `
    -Protocol TCP `
    -Action Allow `
    -LocalPort 22
Warning: The default rule can permit SSH from networks assigned to applicable firewall profiles. If the PC is on a shared, public, or otherwise untrusted network, restrict the permitted source addresses before testing remote access.
For example, to permit only devices on a trusted 192.168.50.0/24 LAN:
Set-NetFirewallRule -Name OpenSSH-Server-In-TCP -RemoteAddress 192.168.50.0/24
To undo that restriction and restore the rule to accept connections from any remote address:
Set-NetFirewallRule -Name OpenSSH-Server-In-TCP -RemoteAddress Any
Do not change the firewall rule if you are connected remotely through the same SSH session unless you have confirmed the new rule includes your current client address.

5. Find the server’s name and local IP address​

On the Windows PC hosting OpenSSH Server, run:
Code:
hostname
ipconfig
Use either:
  • The computer name returned by hostname, such as DESKTOP-ADMIN.
  • The IPv4 address listed for the active Ethernet or Wi-Fi adapter, such as 192.168.50.25.
For the first test, use the IP address. It avoids local DNS or name-resolution problems.

6. Test SSH from another device​

From another Windows device, open PowerShell or Windows Terminal and run:
ssh [email][email protected][/email]
Replace:
  • username with the Windows account name on the SSH server.
  • 192.168.50.25 with the server’s actual IPv4 address.
For a domain account, use this format:
ssh domain\[email][email protected][/email]
On the first connection, SSH displays the server host-key fingerprint and asks whether you want to continue. Verify that you intended to reach that PC, then type:
yes
Enter the Windows account password when prompted. Password characters do not appear while you type.
A successful session usually ends at a prompt similar to:
desktop-admin\username@DESKTOP-ADMIN C:\Users\username>
Run these commands to verify the remote identity and working directory:
Code:
whoami
hostname
cd
Type the following to end the session:
exit

Configure public-key sign-in​

Public-key authentication avoids routine password entry and is strongly preferred before exposing SSH beyond a tightly controlled local network or VPN.

7. Create an SSH key on the client device​

On the device from which you will connect, open PowerShell and run:
ssh-keygen -t ed25519 -a 64 -f $env:USERPROFILE\.ssh\id_ed25519
When prompted:
  1. Press Enter to accept the displayed file location.
  2. Enter a strong passphrase. A passphrase protects the private key if the client device is lost or compromised.
This creates:
Code:
%USERPROFILE%\.ssh\id_ed25519
%USERPROFILE%\.ssh\id_ed25519.pub
The .pub file is the public key. It is safe to copy to the SSH server. Never copy, email, or place the private id_ed25519 file on the server.

8. Add the public key to the Windows account on the server​

For a standard, non-administrator account, sign in locally to the server as that user. Create the .ssh folder and authorized-keys file:
Code:
New-Item -ItemType Directory -Force -Path "$env:USERPROFILE\.ssh"
notepad "$env:USERPROFILE\.ssh\authorized_keys"
On the client, display the public key:
Get-Content "$env:USERPROFILE\.ssh\id_ed25519.pub"
Copy the complete single line, paste it into authorized_keys, save the file, and close Notepad.
For an account that belongs to the local Administrators group, OpenSSH uses a shared administrator key file instead:
C:\ProgramData\ssh\administrators_authorized_keys
Warning: Administrator SSH access gives the connecting account the same broad privileges it has locally. Use a standard account for ordinary administration where possible. If you configure an administrator key, preserve the required file permissions or key authentication can fail.
Copy the public key to a temporary text file on the server, for example C:\Temp\id_ed25519.pub, then run elevated PowerShell:
Code:
New-Item -ItemType Directory -Force -Path "$env:ProgramData\ssh"
Get-Content C:\Temp\id_ed25519.pub |
    Add-Content -Force -Path "$env:ProgramData\ssh\administrators_authorized_keys"

icacls.exe "$env:ProgramData\ssh\administrators_authorized_keys" `
    /inheritance:r `
    /grant "Administrators:F" `
    /grant "SYSTEM:F"
Test the key from the client:
ssh -i $env:USERPROFILE\.ssh\id_ed25519 [email][email protected][/email]
Expected result: after unlocking the private key with its passphrase, the connection opens without asking for the Windows account password.

9. Disable password authentication only after key access works​

Warning: A configuration error or missing key can lock every SSH user out. Keep the existing password-authenticated SSH session open, start a second session to test the key, and ensure you retain local console access before changing this setting.
On the server, open elevated PowerShell and back up the configuration:
Code:
Copy-Item C:\ProgramData\ssh\sshd_config C:\ProgramData\ssh\sshd_config.backup
notepad C:\ProgramData\ssh\sshd_config
Add this line in the global portion of the file, before any Match block:
PasswordAuthentication no
Save the file, validate the configuration, and restart the service:
Code:
C:\Windows\System32\OpenSSH\sshd.exe -t
Restart-Service sshd
The validation command should return no output. Now open a new terminal on the client and confirm that key authentication still works:
ssh -i $env:USERPROFILE\.ssh\id_ed25519 [email][email protected][/email]
If it fails, use the still-open session or local console to restore password authentication:
Code:
Copy-Item C:\ProgramData\ssh\sshd_config.backup C:\ProgramData\ssh\sshd_config -Force
Restart-Service sshd

Troubleshooting and rollback​

OpenSSH Server will not install​

If Add-WindowsCapability returns errors such as 0x800F0954, 0x800F0950, or Windows Update-related errors, the PC may be offline or governed by WSUS, another intranet update service, or a policy that blocks optional-feature downloads.
First, confirm the feature state:
Get-WindowsCapability -Online | Where-Object Name -like 'OpenSSH*'
If the server remains NotPresent, ask the organization’s Windows-update administrator to permit Features on Demand downloads or provide a Features on Demand source matching the exact Windows version and build. Do not install an arbitrary third-party OpenSSH package as a substitute for the built-in feature without a patching and ownership plan.

Start-Service sshd reports that the service does not exist​

The server capability is not installed, or installation did not finish. Re-run:
Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0
Then restart Windows if the installation reports that it is required, and repeat:
Code:
Start-Service sshd
Set-Service sshd -StartupType Automatic

Connection is refused or immediately reset​

On the server, verify the service and firewall rule:
Code:
Get-Service sshd
Get-NetFirewallRule -Name OpenSSH-Server-In-TCP
Get-NetTCPConnection -LocalPort 22 -State Listen
Expected results:
  • sshd is Running.
  • The firewall rule exists and is enabled.
  • A listener exists on TCP port 22.
If another application owns port 22, identify it:
Code:
Get-NetTCPConnection -LocalPort 22 -State Listen |
    Select-Object LocalAddress, LocalPort, OwningProcess

Get-Process -Id <OwningProcess>
Stop or reconfigure the conflicting application rather than changing SSH settings blindly.
From the client, test network reachability:
Test-NetConnection 192.168.50.25 -Port 22
TcpTestSucceeded : True confirms that the client can reach the SSH service. If it is False, check the server firewall rule, the selected network profile, VPN rules, guest Wi-Fi isolation, and the IP address.

The password is rejected​

Confirm that the username format matches the account type:
Code:
ssh [email][email protected][/email]
ssh domain\[email][email protected][/email]
Verify locally that the account can sign in and that you are using the correct password. If you disabled password authentication, password prompts are expected to fail; use the configured private key or restore the backed-up sshd_config file from a local console.

Public-key authentication returns Permission denied (publickey)

Use verbose client output to see whether the correct key is offered:
ssh -vvv -i $env:USERPROFILE\.ssh\id_ed25519 [email][email protected][/email]
Check these common causes:
  • The public key in authorized_keys is incomplete, wrapped onto multiple lines, or copied from the wrong client key.
  • A standard user’s public key is not in C:\Users\username\.ssh\authorized_keys.
  • An administrator’s public key is incorrectly stored in the user profile instead of C:\ProgramData\ssh\administrators_authorized_keys.
  • The administrator key file permissions were changed.
Repair the administrator key-file permissions:
Code:
icacls.exe "C:\ProgramData\ssh\administrators_authorized_keys" `
    /inheritance:r `
    /grant "Administrators:F" `
    /grant "SYSTEM:F"
Then restart the service:
Restart-Service sshd

Remove or fully disable OpenSSH Server​

To immediately stop remote SSH access while retaining the installed feature:
Code:
Stop-Service sshd
Set-Service -Name sshd -StartupType Disabled
Disable-NetFirewallRule -Name OpenSSH-Server-In-TCP
To restore access later:
Code:
Set-Service -Name sshd -StartupType Automatic
Enable-NetFirewallRule -Name OpenSSH-Server-In-TCP
Start-Service sshd
To remove OpenSSH Server entirely, run elevated PowerShell:
Code:
Stop-Service sshd -ErrorAction SilentlyContinue
Remove-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0
Remove-NetFirewallRule -Name OpenSSH-Server-In-TCP -ErrorAction SilentlyContinue
Restart Windows if the removal reports that a restart is required or if the service had active connections.