On this weblog publish, I’ll stroll you thru putting in OpenSSH on Home windows Server 2019, 2022, or 2025 utilizing a PowerShell script.
Chances are high you’re already acquainted with OpenSSH (Open Safe Shell), the open-source implementation of the SSH protocol. It’s the usual for safe distant entry, encrypted communication, and file transfers, and has lengthy been a go-to for Linux directors. Right this moment, it’s additionally a robust device for Home windows directors for cross-platform distant administration.
Beginning with Home windows Server 2019, OpenSSH grew to become accessible as an non-compulsory function. In Home windows Server 2025, it’s even pre-installed by default, although not enabled out of the field.
To automate the set up of OpenSSH on Home windows Server 2019 or Home windows Server 2022, or to allow it on a Home windows Server 2025, I’ve written a PowerShell script. On this weblog publish, I’ll clarify easy methods to use it and stroll you thru the method.
Desk of Contents
Stipulations
- A server (both bodily or digital) working Home windows Server 2019, 2022, or 2025.
- An account that could be a member of the built-in Directors group, which is required to log in to the server and run the script.

PowerShell script
First, let me clarify what this PowerShell script does:
- Examine if PowerShell is working as Administrator, in any other case exit the script.
- Examine if the OS is Home windows Server 2025 and set a flag to manage script execution.
- Set up OpenSSH Server if OS is Home windows Server 2019 or Home windows Server 2022.
- Set up OpenSSH Shopper if OS is Home windows Server 2019 or Home windows Server 2022.
- Begin and allow the SSH service.
- Permit OpenSSH via the Home windows Firewall.
To make use of the script, begin by saving a duplicate as “Set up-OpenSSH-on-a-Home windows-Server-2019-2022-2025.ps1” or obtain it straight from GitHub. Alter the variables to fit your particular wants, after which run the script utilizing Home windows PowerShell (as Administrator) on the server.
💡 I often save the script regionally within the C:Temp folder on the server and run it from there.


## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
## Variables
# Dynamic variables - Please change the values if wanted to suit your surroundings.
$firewallRuleName = "OpenSSH-Server-In" # Variable for the firewall rule title
Set-PSBreakpoint -Variable currenttime -Mode Learn -Motion {$world:currenttime = Get-Date -Format "dddd MM/dd/yyyy HH:mm"} | Out-Null
$foregroundColor1 = "Inexperienced"
$foregroundColor2 = "Yellow"
$foregroundColor3 = "Purple"
$writeEmptyLine = "`n"
$writeSeperatorSpaces = " - "
## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
## Write script began.
Write-Host ($writeEmptyLine + "# Script began. With out errors, it will possibly take as much as 2 minutes to finish" + $writeSeperatorSpaces + $currentTime)`
-foregroundcolor $foregroundColor1 $writeEmptyLine
## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
## Examine if PowerShell is working as Administrator, in any other case exit the script.
$currentPrincipal = New-Object Safety.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())
$isAdministrator = $currentPrincipal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
if ($isAdministrator -eq $false)
{
Write-Host ($writeEmptyLine + "# Please run PowerShell as Administrator" + $writeSeperatorSpaces + $currentTime)`
-foregroundcolor $foregroundColor3 $writeEmptyLine
exit
}
## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
## Examine if the OS is Home windows Server 2025 and set a flag to manage script execution.
attempt {
$osInfo = Get-CimInstance -ClassName Win32_OperatingSystem
if ($osInfo.Caption -like "*Home windows Server 2025*") {
Write-Host ($writeEmptyLine + "# OS is Home windows Server 2025. Persevering with script execution" + $writeSeperatorSpaces + $world:currenttime)`
-foregroundcolor $foregroundColor2 $writeEmptyLine
$isWindowsServer2025 = $true
} else {
# OS is just not Home windows Server 2025, proceed with the script
Write-Host ($writeEmptyLine + "# OS is just not Home windows Server 2025. Persevering with script execution" + $writeSeperatorSpaces + $world:currenttime)`
-foregroundcolor $foregroundColor2 $writeEmptyLine
$isWindowsServer2025 = $false
}
} catch {
Write-Host ($writeEmptyLine + "# Did not retrieve OS data: $($_.Exception.Message)" + $writeSeperatorSpaces + $world:currenttime)`
-foregroundcolor $foregroundColor3 $writeEmptyLine
exit
}
## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
## Set up OpenSSH Server if OS is Home windows Server 2019 or Home windows Server 2022.
if (-not $isWindowsServer2025) {
attempt Out-Null
Write-Host ($writeEmptyLine + "# OpenSSH Server put in" + $writeSeperatorSpaces + $world:currenttime)`
-foregroundcolor $foregroundColor2 $writeEmptyLine
catch {
Write-Host ($writeEmptyLine + "# Failed to put in OpenSSH Server: $($_.Exception.Message)" + $writeSeperatorSpaces + $world:currenttime)`
-foregroundcolor $foregroundColor3 $writeEmptyLine
exit
}
}
## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
## Set up OpenSSH Shopper if OS is Home windows Server 2019 or Home windows Server 2022.
if (-not $isWindowsServer2025) {
attempt Out-Null
Write-Host ($writeEmptyLine + "# OpenSSH Shopper put in" + $writeSeperatorSpaces + $world:currenttime)`
-foregroundcolor $foregroundColor2 $writeEmptyLine
catch {
Write-Host ($writeEmptyLine + "# Failed to put in OpenSSH Shopper: $($_.Exception.Message)" + $writeSeperatorSpaces + $world:currenttime)`
-foregroundcolor $foregroundColor3 $writeEmptyLine
exit
}
}
## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
## Begin and allow the SSH service.
attempt {
# Begin the SSH service
Begin-Service sshd
# Set the SSH service to begin mechanically with Home windows
Set-Service -Identify sshd -StartupType Automated
Write-Host ($writeEmptyLine + "# SSH service began and set to automated" + $writeSeperatorSpaces + $world:currenttime)`
-foregroundcolor $foregroundColor2 $writeEmptyLine
} catch {
Write-Host ($writeEmptyLine + "# Failed to begin or configure SSH service: $($_.Exception.Message)" + $writeSeperatorSpaces + $world:currenttime)`
-foregroundcolor $foregroundColor3 $writeEmptyLine
exit
}
## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
## Permit OpenSSH via the Home windows Firewall.
attempt {
# Examine if the firewall rule already exists
$firewallRule = Get-NetFirewallRule -Identify $firewallRuleName -ErrorAction SilentlyContinue
if ($null -eq $firewallRule) Out-Null
Write-Host ($writeEmptyLine + "# Home windows Firewall rule created and configured for OpenSSH" + $writeSeperatorSpaces + $world:currenttime)`
-foregroundcolor $foregroundColor2 $writeEmptyLine
else {
# Rule already exists
Write-Host ($writeEmptyLine + "# Home windows Firewall rule already exists and is configured for OpenSSH" + $writeSeperatorSpaces + $world:currenttime)`
-foregroundcolor $foregroundColor2 $writeEmptyLine
}
} catch {
Write-Host ($writeEmptyLine + "# Did not configure Home windows Firewall for OpenSSH: $($_.Exception.Message)" + $writeSeperatorSpaces + $world:currenttime)`
-foregroundcolor $foregroundColor3 $writeEmptyLine
exit
}
## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
## Write script accomplished.
Write-Host ($writeEmptyLine + "# Script accomplished" + $writeSeperatorSpaces + $currentTime)`
-foregroundcolor $foregroundColor1 $writeEmptyLine
## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Utilizing the script on supported Home windows Server OSes
Home windows Server 2019

After working the script, you’ll be able to examine if OpenSSH was efficiently put in by working the next command in PowerShell:
Get-WindowsCapability -On-line | The place-Object Identify -like 'OpenSSH*'

You can too examine the Companies panel (press Win + R, kind companies.msc, and hit Enter) to see if the OpenSSH SSH Server service is working and has its Startup Kind set to Automated.


Home windows Server 2022

After working the script, you’ll be able to examine if OpenSSH was efficiently put in by working the next command in PowerShell:
Get-WindowsCapability -On-line | The place-Object Identify -like 'OpenSSH*'

You can too examine the Companies panel (press Win + R, kind companies.msc, and hit Enter) to see if the OpenSSH SSH Server service is working and has its Startup Kind set to Automated.


Home windows Server 2025

After working the script, you’ll be able to confirm that OpenSSH was efficiently put in by opening Server Supervisor and checking that Distant SSH Entry is marked as Enabled, or by working the PowerShell command talked about earlier within the Home windows Server 2019 or 2022 part.


Connecting to an OpenSSH Server on Home windows Server
To connect with an OpenSSH server working on a Home windows Server that’s a part of a website, you should utilize any SSH consumer, akin to PowerShell, Home windows Terminal, PuTTY, or KiTTY.
For those who’re utilizing Home windows Terminal or PowerShell, use the next command format:
ssh domainusername@servername
Choose Sure in case you’re connecting for the primary time. This provides the server to the listing of recognized SSH hosts in your Home windows consumer.
The service will then immediate you on your password. As a safety precaution, your password characters received’t be displayed as you kind.
As soon as related, it is best to see the usual Home windows command shell immediate, the place you’ll be able to run instructions to handle the server, set up new options, troubleshoot points, or carry out different operational duties.


When connecting to an OpenSSH server working on a Home windows Server that’s not a part of a website (i.e., a standalone server), the simplest methodology is to make use of PuTTY or KiTTY, connecting by way of its IP handle and an area administrator account.
💡 This after all additionally works for a domain-joined Home windows server that has been configured for OpenSSH.


💡 The primary time you join, PuTTY will immediate you to confirm the server’s host key. Click on Settle for in case you belief the connection.

Subsequent, PuTTY will immediate you to enter the username and password for the server. Merely log in with the proper credentials. As soon as related, you’ll be capable to work together with the server straight via the PuTTY terminal window.



Conclusion
On this weblog publish, I confirmed how you should utilize a PowerShell script to put in OpenSSH on Home windows Server 2019, 2022, or 2025.
I hope the script turns out to be useful when organising OpenSSH on any of your servers. When you have any questions or solutions, be at liberty to achieve out on X (@wmatthyssen) or depart a remark under.