How to Configure OpenSSH Server on Windows Server 2025
OpenSSH has been a first-class optional feature of Windows Server since 2019, and on Windows Server 2025 it receives further polish that makes it a genuinely production-ready alternative to WinRM for remote administration. SSH offers a universally understood protocol, strong key-based authentication, encrypted channel multiplexing, and native support in every major scripting language and DevOps toolchain — including Ansible, Terraform, and GitHub Actions. Configuring OpenSSH Server on Windows Server 2025 lets Linux administrators manage Windows hosts with familiar ssh commands, enables key-based authentication for unattended automation, and integrates cleanly with Active Directory accounts and group policy. This guide covers installation, service configuration, the sshd_config options that differ significantly from Linux defaults, public key authentication for both standard and administrator accounts, and testing from a Linux client.
Prerequisites
- Windows Server 2025 (Standard or Datacenter) — domain-joined or workgroup
- Administrator privileges on the target server
- Internet access (for capability installation from Windows Update), or the capability available via WSUS/DISM offline package
- TCP port 22 accessible between the client and server (check edge firewall)
- A Linux or Windows SSH client for testing (built-in
ssh.exeis included in Windows 10/11 and Server 2025)
Step 1 — Install OpenSSH Server
OpenSSH Server is delivered as a Windows optional capability, separate from the client tools. Both should be installed on a server you plan to administer remotely.
# Check what OpenSSH capabilities are available
Get-WindowsCapability -Online | Where-Object Name -like "OpenSSH*"
# Expected output:
# Name : OpenSSH.Client~~~~0.0.1.0 — State: Installed (present by default)
# Name : OpenSSH.Server~~~~0.0.1.0 — State: NotPresent
# Install the OpenSSH Server capability
Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0
# Verify successful installation
Get-WindowsCapability -Online | Where-Object Name -like "OpenSSH.Server*"
# State should now show: Installed
Installation places the OpenSSH binaries in C:WindowsSystem32OpenSSH and creates the sshd and ssh-agent Windows services. It also creates the default configuration directory at C:ProgramDatassh.
# Start the SSH server daemon
Start-Service sshd
# Set sshd to start automatically on boot
Set-Service -Name sshd -StartupType Automatic
# Also start and configure the SSH Agent (used for key management)
Start-Service ssh-agent
Set-Service -Name ssh-agent -StartupType Automatic
# Verify both services are running
Get-Service sshd, ssh-agent | Select-Object Name, Status, StartType
Step 2 — Configure the Windows Firewall Rule
The OpenSSH installer creates a firewall rule automatically, but verifying and optionally restricting it is a good security practice, particularly for servers in multi-homed or DMZ configurations.
# Verify the auto-created firewall rule
Get-NetFirewallRule -Name "OpenSSH-Server-In-TCP" | Select-Object Name, Enabled, Direction, Action
# The rule allows all remote addresses by default — restrict it if needed
Set-NetFirewallRule -Name "OpenSSH-Server-In-TCP" -RemoteAddress "10.10.0.0/16"
# If the rule was not created, create it manually
New-NetFirewallRule `
-Name "OpenSSH-Server-In-TCP" `
-DisplayName "OpenSSH SSH Server (sshd)" `
-Description "Inbound rule for OpenSSH Server (sshd)" `
-Direction Inbound `
-Protocol TCP `
-LocalPort 22 `
-Action Allow `
-Enabled True `
-Profile Any
# If running on a non-standard port (recommended for internet-facing servers)
New-NetFirewallRule `
-Name "OpenSSH-Server-In-TCP-2222" `
-DisplayName "OpenSSH SSH Server on port 2222" `
-Direction Inbound `
-Protocol TCP `
-LocalPort 2222 `
-Action Allow `
-Enabled True
Step 3 — Configure sshd_config
The OpenSSH server configuration file lives at C:ProgramDatasshsshd_config. The Windows version has several important differences from the Linux default, most notably around the location of authorized keys for administrator accounts. Pay close attention to these Windows-specific settings.
# Open sshd_config in a text editor
notepad "C:ProgramDatasshsshd_config"
# Or edit with PowerShell (key settings to configure):
$SshdConfig = "C:ProgramDatasshsshd_config"
# --- Key sshd_config settings for Windows Server 2025 ---
# Port 22 # default; change for security if internet-facing
# AddressFamily any
# ListenAddress 0.0.0.0
# Authentication methods
# PasswordAuthentication yes # set to 'no' once key auth is confirmed working
# PubkeyAuthentication yes # default; ensure this is not commented out
# IMPORTANT Windows-specific: authorized_keys location
# For standard (non-administrator) users:
# AuthorizedKeysFile .ssh/authorized_keys ← per-user home directory
# For LOCAL administrators group members, Windows uses a central file:
# AuthorizedKeysFile __PROGRAMDATA__/ssh/administrators_authorized_keys
# The commented-out default in Windows sshd_config includes BOTH lines.
# To require the central file for admins, ensure this is present and uncommented:
# AuthorizedKeysFile __PROGRAMDATA__/ssh/administrators_authorized_keys
# Subsystem for SFTP
# Subsystem sftp sftp-server.exe
# Logging
# SyslogFacility LOCAL0
# LogLevel INFO
# Use PowerShell to modify specific settings without a text editor:
# Enable public key auth and disable password auth (after setting up keys)
(Get-Content $SshdConfig) -replace '^#?PasswordAuthentications+w+', 'PasswordAuthentication no' |
Set-Content $SshdConfig
# Change SSH port to 2222 (optional)
(Get-Content $SshdConfig) -replace '^#?Ports+d+', 'Port 2222' |
Set-Content $SshdConfig
# Restart sshd to apply config changes
Restart-Service sshd
Step 4 — Set Up Public Key Authentication
Public key authentication is the recommended method for unattended scripts and for eliminating password-based login entirely. The setup differs for administrator vs. non-administrator accounts.
For Standard (Non-Administrator) Users
# On the Windows server — create the .ssh directory for a standard user
$UserHome = "C:Usersjdoe"
New-Item -Path "$UserHome.ssh" -ItemType Directory -Force
# Create the authorized_keys file and add the user's public key
$PublicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIExamplePublicKeyHere ansible@control-node"
Set-Content -Path "$UserHome.sshauthorized_keys" -Value $PublicKey -Encoding UTF8
# Set correct NTFS permissions (OpenSSH requires strict permissions on this file)
$Acl = Get-Acl "$UserHome.sshauthorized_keys"
$Acl.SetAccessRuleProtection($true, $false) # disable inheritance
$Rule = New-Object System.Security.AccessControl.FileSystemAccessRule(
"jdoe", "FullControl", "Allow"
)
$Acl.AddAccessRule($Rule)
Set-Acl -Path "$UserHome.sshauthorized_keys" -AclObject $Acl
For Local Administrator Accounts
# Administrators use a central authorized_keys file
$AdminKeysFile = "C:ProgramDatasshadministrators_authorized_keys"
# Add public keys (one per line)
$AdminPublicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAdminPublicKeyHere admin@jumphost"
Add-Content -Path $AdminKeysFile -Value $AdminPublicKey -Encoding UTF8
# This file MUST be owned by SYSTEM or Administrators and not writable by others
# Fix permissions:
$Acl = Get-Acl $AdminKeysFile
$Acl.SetAccessRuleProtection($true, $false)
$SystemRule = New-Object System.Security.AccessControl.FileSystemAccessRule(
"SYSTEM", "FullControl", "Allow"
)
$AdminRule = New-Object System.Security.AccessControl.FileSystemAccessRule(
"Administrators", "FullControl", "Allow"
)
$Acl.AddAccessRule($SystemRule)
$Acl.AddAccessRule($AdminRule)
Set-Acl -Path $AdminKeysFile -AclObject $Acl
# Restart sshd after modifying authorized_keys or sshd_config
Restart-Service sshd
Step 5 — Set PowerShell as the Default Shell
By default, OpenSSH on Windows Server 2025 drops users into cmd.exe. Setting PowerShell (or PowerShell 7) as the default login shell provides a far more capable remote session.
# Set Windows PowerShell 5.1 as the default SSH shell
New-ItemProperty `
-Path "HKLM:SOFTWAREOpenSSH" `
-Name "DefaultShell" `
-Value "C:WindowsSystem32WindowsPowerShellv1.0powershell.exe" `
-PropertyType String `
-Force
# OR set PowerShell 7 if installed (recommended)
New-ItemProperty `
-Path "HKLM:SOFTWAREOpenSSH" `
-Name "DefaultShell" `
-Value "C:Program FilesPowerShell7pwsh.exe" `
-PropertyType String `
-Force
# Optionally configure default shell arguments
New-ItemProperty `
-Path "HKLM:SOFTWAREOpenSSH" `
-Name "DefaultShellCommandOption" `
-Value "/c" `
-PropertyType String `
-Force
# Restart sshd for the registry change to take effect
Restart-Service sshd
# Verify the registry value
Get-ItemProperty -Path "HKLM:SOFTWAREOpenSSH" -Name DefaultShell
Step 6 — Test from a Linux Client
# On the Linux client — test password authentication first
ssh [email protected]
# Test with a specific key file
ssh -i ~/.ssh/id_ed25519 [email protected]
# Test non-standard port
ssh -p 2222 -i ~/.ssh/id_ed25519 [email protected]
# Run a remote PowerShell command without interactive session
ssh [email protected] "Get-ComputerInfo | Select-Object WindowsProductName, OsVersion"
# Use SCP to copy files (SFTP subsystem must be enabled in sshd_config)
scp -i ~/.ssh/id_ed25519 localfile.txt [email protected]:"C:/Temp/"
# Use SFTP interactively
sftp -i ~/.ssh/id_ed25519 [email protected]
# Set up ~/.ssh/config on the Linux client for convenience
cat >> ~/.ssh/config <<EOF
Host ws2025-01
HostName ws2025-01.contoso.com
User Administrator
Port 22
IdentityFile ~/.ssh/id_ed25519
ServerAliveInterval 60
EOF
ssh ws2025-01 # now connects with all settings applied
Conclusion
OpenSSH Server on Windows Server 2025 delivers a mature, standards-compliant SSH implementation that integrates naturally with the broader DevOps toolchain. By installing the optional capability, configuring sshd_config with the Windows-specific authorized keys paths, setting proper NTFS permissions, and choosing PowerShell as the default shell, you get a remote management channel that is immediately familiar to any Linux or macOS administrator. Public key authentication eliminates password exposure, and the central administrators_authorized_keys file gives you a single location to manage access for privileged accounts across the fleet. Combined with tools like Ansible’s ansible_connection: ssh, Terraform remote-exec provisioners, or simple shell scripts, OpenSSH on Windows Server 2025 is a compelling alternative to WinRM for modern, cross-platform infrastructure management.