Created
March 19, 2025 05:45
-
-
Save ryanreece/b443b520639b5304601d917d4825968f to your computer and use it in GitHub Desktop.
This script configures Windows Remote Management (WinRM) to use HTTPS. It finds an appropriate certificate, creates an HTTPS listener, and configures the Windows Firewall to allow WinRM HTTPS traffic.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
############################################################################# | |
# Configure-WinRMHTTPS.ps1 | |
# | |
# Description: | |
# This script configures Windows Remote Management (WinRM) to use HTTPS. | |
# It finds an appropriate certificate, creates an HTTPS listener, | |
# and configures the Windows Firewall to allow WinRM HTTPS traffic. | |
# | |
# Requirements: | |
# - Run as Administrator | |
# - A valid SSL certificate for the server must exist in the certificate store | |
# | |
# Usage: | |
# .\Configure-WinRMHttps.ps1 | |
############################################################################# | |
# Prompt the user for the server hostname - this should match the certificate name | |
$hostname = Read-Host "Enter the server hostname (e.g., your-server.example.com)" | |
# Get the latest valid certificate matching the hostname from the LocalMachine store | |
# Sorts by expiration date descending to get the most recently issued certificate | |
$cert = Get-ChildItem Cert:\LocalMachine\My | | |
Where-Object { $_.Subject -like "*$hostname*" } | | |
Sort-Object NotAfter -Descending | | |
Select-Object -First 1 | |
# Check if a WinRM HTTPS listener already exists | |
$existingListener = winrm enumerate winrm/config/Listener | Select-String -Pattern "Transport = HTTPS" | |
if ($cert) { | |
# Remove any spaces from the thumbprint (sometimes present in certain outputs) | |
$thumbprint = $cert.Thumbprint -replace "\s", "" | |
Write-Output "Found certificate with thumbprint: $thumbprint" | |
Write-Output "Certificate subject: $($cert.Subject)" | |
Write-Output "Certificate expires: $($cert.NotAfter)" | |
# If a listener exists, delete it to update with the new certificate | |
if ($existingListener) { | |
Write-Output "Existing WinRM HTTPS listener found. Removing to update certificate..." | |
winrm delete winrm/config/Listener?Address=*+Transport=HTTPS | |
} else { | |
Write-Output "No existing WinRM HTTPS listener found. Creating a new one..." | |
} | |
# Create a new WinRM HTTPS listener using New-WSManInstance | |
# This is the preferred method over the direct winrm command | |
$listenerParams = @{ | |
ResourceURI = 'winrm/config/listener' | |
SelectorSet = @{ | |
Transport = "HTTPS" | |
Address = "*" # Listen on all IP addresses | |
} | |
ValueSet = @{ | |
CertificateThumbprint = $thumbprint | |
Enabled = $true | |
Port = 5986 # Standard port for WinRM over HTTPS | |
} | |
} | |
try { | |
New-WSManInstance @listenerParams | |
Write-Output "WinRM HTTPS listener successfully created with certificate: $thumbprint" | |
} catch { | |
Write-Error "Failed to create WinRM listener: $_" | |
exit 1 | |
} | |
# Optional: Restart the WinRM service to apply changes | |
# Uncomment if you want to restart automatically | |
# Write-Output "Restarting WinRM service..." | |
# Restart-Service WinRM | |
Write-Output "WinRM HTTPS configuration completed successfully." | |
} else { | |
Write-Error "No valid certificate found for hostname: $hostname" | |
Write-Output "Please ensure a certificate with a subject name matching '$hostname' exists in the local machine certificate store." | |
exit 1 | |
} | |
# Define the firewall rule name for WinRM HTTPS | |
$ruleName = "WinRM over HTTPS" | |
# Check if the firewall rule already exists to avoid duplicates | |
$existingRule = Get-NetFirewallRule -DisplayName $ruleName -ErrorAction SilentlyContinue | |
if (-not $existingRule) { | |
# Create the firewall rule to allow incoming connections on port 5986 | |
Write-Output "Creating firewall rule to allow WinRM HTTPS traffic..." | |
New-NetFirewallRule -DisplayName $ruleName -Direction Inbound -Protocol TCP -LocalPort 5986 -Action Allow | |
Write-Output "Firewall rule '$ruleName' created successfully." | |
} else { | |
Write-Output "Firewall rule '$ruleName' already exists. No changes needed." | |
} | |
Write-Output "`nSetup complete! WinRM is now configured to use HTTPS on port 5986." | |
Write-Output "You can connect to this server using: Enter-PSSession -ComputerName $hostname -UseSSL" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment