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.exe is 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.