At DeployHQ, we're all about making developers' lives easier through automation. A common friction point for teams working in mixed environments is dealing with different deployment setups for Windows and Linux. While SSH is the standard for Linux, setting it up on Windows has traditionally been a manual, multi-step process.
What if you could configure OpenSSH Server on any Windows machine with a single, reliable script? This would allow you to use the same secure, key-based deployment method you use on Linux, paving the way for consistent, automated deployments with tools like DeployHQ.
Today, we're sharing a powerful PowerShell script that does just that. It installs and configures the OpenSSH server on Windows, letting you choose between key-only authentication (the most secure method) or a combination of password and key.
PowerShell to Rule Them All
This script is designed to be run with Administrator privileges in PowerShell 5.1 or later. It automates the entire process: checking for an existing installation, installing OpenSSH Server if needed, starting the required services, and configuring the sshd_config
file for your chosen authentication method.
# Requires PowerShell 5.1 or later for some cmdlets
# Run this script with Administrator privileges
param(
[ValidateSet('KeyOnly', 'PasswordAndKey')]
[string]$AuthenticationMethod = 'KeyOnly' # Default value is 'KeyOnly'
)
$sshdConfigPath = "$env:ProgramData\ssh\sshd_config"
Write-Host "--- OpenSSH Server Setup and Configuration Script ---"
Write-Host "Authentication Method Selected: $AuthenticationMethod"
# --- 1. Check for OpenSSH Server Installation ---
Write-Host "Checking if OpenSSH Server is already installed..."
$isInstalled = $false
try {
$openSshCapability = Get-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0 -ErrorAction SilentlyContinue
if ($openSshCapability -and $openSshCapability.State -eq 'Installed') {
Write-Host "OpenSSH Server is already installed. Skipping installation."
$isInstalled = $true
} else {
Write-Host "OpenSSH Server is not installed."
}
} catch {
Write-Warning "Could not determine OpenSSH Server installation status using Get-WindowsCapability. Attempting to install anyway."
}
# --- 2. Install OpenSSH Server if not already installed ---
if (-not $isInstalled) {
Write-Host "Installing OpenSSH Server..."
try {
Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0 -ErrorAction Stop
Write-Host "OpenSSH Server installed successfully."
Write-Host "Starting sshd service..."
Start-Service sshd -ErrorAction Stop
Write-Host "sshd service started."
Write-Host "Setting sshd service to start automatically..."
Set-Service -Name sshd -StartupType Automatic -ErrorAction Stop
Write-Host "sshd service set to automatic startup."
} catch {
Write-Error "Failed to install or start OpenSSH Server: $($_.Exception.Message)"
Write-Warning "Please ensure you are running PowerShell as Administrator and have internet access."
exit 1 # Exit if installation fails
}
} else {
# Ensure the service is running even if already installed
try {
$service = Get-Service -Name sshd -ErrorAction SilentlyContinue
if ($service) {
if ($service.Status -ne 'Running') {
Write-Host "sshd service is not running. Starting it now..."
Start-Service sshd -ErrorAction Stop
Write-Host "sshd service started."
}
if ($service.StartupType -ne 'Automatic') {
Write-Host "sshd service is not set to automatic. Setting it now..."
Set-Service -Name sshd -StartupType Automatic -ErrorAction Stop
Write-Host "sshd service set to automatic startup."
}
} else {
Write-Warning "sshd service not found. This is unexpected if OpenSSH Server is reported as installed. Manual check recommended."
}
} catch {
Write-Warning "Could not manage sshd service. Please check its status manually. Error: $($_.Exception.Message)"
}
}
# --- 3. Configure sshd_config ---
Write-Host "Configuring sshd_config based on '$AuthenticationMethod'..."
if (-not (Test-Path $sshdConfigPath)) {
Write-Error "sshd_config file not found at '$sshdConfigPath'. OpenSSH Server might not be fully installed or configured correctly."
exit 1
}
try {
# Read the content of the file
$configContent = Get-Content -Path $sshdConfigPath -Raw
# --- Configure PasswordAuthentication ---
$passwordAuthLine = "PasswordAuthentication "
if ($AuthenticationMethod -eq 'KeyOnly') {
$passwordAuthLine += "no"
Write-Host "Setting 'PasswordAuthentication no'."
} else { # PasswordAndKey
$passwordAuthLine += "yes"
Write-Host "Setting 'PasswordAuthentication yes'."
}
if ($configContent -match '(?i)^\s*#?\s*PasswordAuthentication\s+(yes|no)') {
$configContent = $configContent -replace '(?i)^\s*#?\s*PasswordAuthentication\s+(yes|no)', $passwordAuthLine
} else {
# Add the line if it doesn't exist
$configContent += "`n$passwordAuthLine"
}
# --- Configure PubkeyAuthentication ---
$pubkeyAuthLine = "PubkeyAuthentication yes" # Always enable for either method
Write-Host "Setting 'PubkeyAuthentication yes'."
if ($configContent -match '(?i)^\s*#?\s*PubkeyAuthentication\s+(yes|no)') {
$configContent = $configContent -replace '(?i)^\s*#?\s*PubkeyAuthentication\s+(yes|no)', $pubkeyAuthLine
} else {
# Add the line if it doesn't exist
$configContent += "`n$pubkeyAuthLine"
}
# Ensure AuthorizedKeysFile is set and uncommented
$authorizedKeysFileLine = "AuthorizedKeysFile .ssh/authorized_keys"
if ($configContent -notmatch '(?i)^\s*#?\s*AuthorizedKeysFile\s+\S+') {
$configContent += "`n$authorizedKeysFileLine"
Write-Host "Added default 'AuthorizedKeysFile .ssh/authorized_keys'."
} elseif ($configContent -match '(?i)^\s*#\s*AuthorizedKeysFile\s+.ssh/authorized_keys') {
$configContent = $configContent -replace '(?i)^\s*#\s*AuthorizedKeysFile\s+.ssh/authorized_keys', $authorizedKeysFileLine
Write-Host "Uncommented 'AuthorizedKeysFile .ssh/authorized_keys'."
}
# Write the modified content back to the file
Set-Content -Path $sshdConfigPath -Value $configContent -Force
Write-Host "sshd_config updated successfully."
# --- 4. Restart sshd service to apply changes ---
Write-Host "Restarting sshd service to apply new configuration..."
Restart-Service sshd -ErrorAction Stop
Write-Host "sshd service restarted. OpenSSH Server configured."
} catch {
Write-Error "Failed to configure sshd_config or restart service: $($_.Exception.Message)"
exit 1
}
Write-Host "--- Script Finished ---"
Write-Host "Remember to add public keys to 'C:\Users\YourUser\.ssh\authorized_keys' for your users if you chose 'KeyOnly' or plan to use key authentication."
How to Run the Script
Save the code above as a PowerShell script file, for example,
Configure-OpenSSH.ps1
.Open PowerShell as an Administrator.
Navigate to the directory where you saved the file.
Option 1: Default (Key-Only Authentication)
For the most secure setup, run the script without any parameters. This will disable password-based logins and enforce SSH key authentication.
.\Configure-OpenSSH.ps1
Option 2: Enable Password and Key Authentication
If you need to allow both password and SSH key authentication as a fallback, run the script with the AuthenticationMethod
parameter set to PasswordAndKey
.
.\Configure-OpenSSH.ps1 -AuthenticationMethod PasswordAndKey
What the Script Does
Checks for OpenSSH: It first verifies if the OpenSSH Server feature is already installed to avoid redundant work.
Installs and Starts Services: If not installed, it adds the Windows Capability for the server, starts the
sshd
service, and sets it to launch automatically on boot.Configures
sshd_config
: This is the core of the automation. The script reads thesshd_config
file and intelligently modifies it:
- It sets `PasswordAuthentication` to `no` or `yes` based on your chosen method.
- It ensures `PubkeyAuthentication` is set to `yes`, which is essential for key-based deployments.
- It verifies that the `AuthorizedKeysFile` directive is correctly pointing to `.ssh/authorized_keys` and is not commented out.
- Applies Changes: Finally, it restarts the
sshd
service to ensure all the new configuration settings are applied immediately.
Unlocking Automated Deployments with DeployHQ
With OpenSSH running on your Windows server, you can now treat it just like a Linux machine in your DeployHQ projects. Simply add a new server using the standard SSH connection type, point it to your server's IP or hostname, and add the project's public key to the appropriate C:\Users\YourUser\.ssh\authorized_keys
file on the Windows machine.
This simple script removes a major hurdle in cross-platform development, enabling you to build a single, streamlined deployment pipeline for all your servers, regardless of their operating system.
We at DeployHQ, have customers that have cut their expenses by following this strategy, and our support team is always happy to help :)
Top comments (0)