How to Configure WinRM Security on Windows Server 2012 R2

Windows Remote Management (WinRM) is the Microsoft implementation of the WS-Management protocol and is the foundation of PowerShell remoting, CIM sessions, Server Manager remote management, and many automation frameworks. WinRM is powerful, but an improperly configured WinRM listener exposes the server to credential theft, unauthorized remote code execution, and man-in-the-middle attacks. This guide covers securing WinRM by restricting listener access, requiring HTTPS transport, configuring authentication methods, and monitoring remote management activity.

Prerequisites

  • Local Administrator access to configure WinRM settings
  • An SSL certificate from an internal or commercial CA for HTTPS listener configuration
  • Windows Server 2012 R2 with PowerShell 4.0 or later
  • Understanding that changing WinRM authentication or transport settings will disrupt existing PowerShell remoting sessions

Step 1: Audit Current WinRM Configuration

# View current WinRM configuration
winrm get winrm/config

# List all WinRM listeners
winrm enumerate winrm/config/listener

# Check which authentication methods are enabled
winrm get winrm/config/service/auth

# Check if WinRM is running
Get-Service WinRM

Step 2: Configure WinRM via HTTPS Only

By default, winrm quickconfig creates an HTTP listener on port 5985, which transmits credentials and commands in cleartext (though Kerberos authentication is encrypted separately). Replace the HTTP listener with HTTPS:

# Get the thumbprint of the server's SSL certificate
$cert = Get-ChildItem Cert:LocalMachineMy |
    Where-Object { $_.Subject -match "CN=$env:COMPUTERNAME" -and $_.HasPrivateKey } |
    Sort-Object NotAfter -Descending |
    Select-Object -First 1

$thumbprint = $cert.Thumbprint
Write-Host "Using certificate: $($cert.Subject) - Thumbprint: $thumbprint"

# Delete existing HTTP listener
winrm delete winrm/config/listener?Address=*+Transport=HTTP

# Create HTTPS listener
winrm create winrm/config/Listener?Address=*+Transport=HTTPS "@{Hostname=`"$env:COMPUTERNAME`";CertificateThumbprint=`"$thumbprint`"}"

# Verify HTTPS listener is active
winrm enumerate winrm/config/listener

Open the Windows Firewall for WinRM HTTPS (port 5986) and close HTTP (port 5985):

# Allow WinRM HTTPS through Windows Firewall
New-NetFirewallRule `
    -DisplayName "Allow WinRM HTTPS" `
    -Direction Inbound `
    -Protocol TCP `
    -LocalPort 5986 `
    -RemoteAddress "10.0.100.0/24" `  # Restrict to management network
    -Action Allow

# Remove or disable the WinRM HTTP firewall rule
Get-NetFirewallRule -DisplayName "*Windows Remote Management*" |
    Where-Object { $_.Description -match "5985|HTTP" } |
    Disable-NetFirewallRule

Step 3: Disable Insecure Authentication Methods

WinRM supports several authentication mechanisms. Disable the weaker ones:

# Disable Basic authentication (sends credentials in base64-encoded cleartext)
Set-Item WSMan:localhostServiceAuthBasic -Value $false

# Disable Digest authentication (weak credential protection)
Set-Item WSMan:localhostServiceAuthDigest -Value $false

# Disable CredSSP (if not specifically needed for double-hop scenarios)
Set-Item WSMan:localhostServiceAuthCredSSP -Value $false

# Keep Kerberos and Negotiate enabled (Kerberos is used in domain environments)
Set-Item WSMan:localhostServiceAuthKerberos -Value $true
Set-Item WSMan:localhostServiceAuthNegotiate -Value $true

# Verify
winrm get winrm/config/service/auth

Step 4: Restrict WinRM Access via Trusted Hosts and IP Filters

In a domain environment, Kerberos handles authentication and TrustedHosts is not required. In workgroup environments, restrict which computers can connect:

# For domain environments - verify TrustedHosts is empty (Kerberos handles authentication)
Get-Item WSMan:localhostClientTrustedHosts

# For workgroup environments - limit to specific management server IPs
Set-Item WSMan:localhostClientTrustedHosts -Value "10.0.100.10,10.0.100.11" -Force

# Configure AllowedRemoteAddresses IP filter to restrict inbound WinRM
winrm set winrm/config/service '@{AllowedRemoteAddresses="10.0.100.0/255.255.255.0"}'

Step 5: Configure PowerShell Remoting Session Security

PowerShell remoting sessions run in a constrained endpoint by default. Create custom constrained endpoints that limit what remote sessions can do:

# Create a constrained PowerShell endpoint (JEA - Just Enough Administration)
# Create a role capability file
New-Item -Path "C:JEA" -ItemType Directory -Force

$jrFile = @{
    Path = "C:JEAServerOpsRole.psrc"
    Description = "Limited server operations role"
    VisibleCmdlets = @(
        "Get-Service", "Get-Process",
        "Get-EventLog", "Get-NetIPAddress",
        @{Name="Restart-Service"; Parameters=@{Name="Name"; ValidateSet="W32Time","DNS"}}
    )
    VisibleFunctions = @()
    VisibleExternalCommands = @()
}
New-PSRoleCapabilityFile @jrFile

# Register a constrained endpoint
$sessionConfig = @{
    Name = "ServerOps"
    TransportOption = New-PSTransportOption -MaxIdleTimeoutSec 3600
    ShowSecurityDescriptorUI = $false
    RunAsVirtualAccount = $true
    RoleDefinitions = @{
        "CORPServerOperators" = @{ RoleCapabilities = "ServerOpsRole" }
    }
}
Register-PSSessionConfiguration @sessionConfig -Force

Step 6: Enable WinRM Logging and Monitoring

# Enable WinRM operational log
wevtutil sl Microsoft-Windows-WinRM/Operational /enabled:true /ms:52428800

# Enable PowerShell Script Block Logging (captures all PowerShell executed in remote sessions)
Set-ItemProperty -Path "HKLM:SOFTWAREPoliciesMicrosoftWindowsPowerShellScriptBlockLogging" `
    -Name "EnableScriptBlockLogging" -Value 1 -Type DWord -Force

# Enable PowerShell Module Logging
Set-ItemProperty -Path "HKLM:SOFTWAREPoliciesMicrosoftWindowsPowerShellModuleLogging" `
    -Name "EnableModuleLogging" -Value 1 -Type DWord -Force

# Set module logging to capture all modules
New-Item -Path "HKLM:SOFTWAREPoliciesMicrosoftWindowsPowerShellModuleLoggingModuleNames" -Force | Out-Null
Set-ItemProperty -Path "HKLM:SOFTWAREPoliciesMicrosoftWindowsPowerShellModuleLoggingModuleNames" `
    -Name "*" -Value "*" -Type String

# Monitor WinRM connection events
Get-WinEvent -LogName "Microsoft-Windows-WinRM/Operational" -MaxEvents 50 |
    Select-Object TimeCreated, Id, Message | Format-List

Step 7: Configure GPO for WinRM Security

Deploy WinRM security settings via Group Policy for consistency across all servers:

Navigate to Computer Configuration → Administrative Templates → Windows Components → Windows Remote Management (WinRM) → WinRM Service:

  • Allow remote server management through WinRM — Enabled; IPv4 filter: restrict to management network (e.g., 10.0.100.*)
  • Allow Basic authentication — Disabled
  • Allow CredSSP authentication — Disabled
  • Disallow Negotiate authentication — Disabled (keep Negotiate enabled)

Step 8: Test Secure WinRM Connection

# Test HTTPS WinRM connection from a management workstation
$sessionOption = New-PSSessionOption -SkipCACheck:$false -SkipCNCheck:$false
$session = New-PSSession -ComputerName "SERVER01" -UseSSL -SessionOption $sessionOption

# If using a self-signed cert (testing only - not for production):
# $sessionOption = New-PSSessionOption -SkipCACheck -SkipCNCheck -SkipRevocationCheck

Invoke-Command -Session $session -ScriptBlock { Get-ComputerInfo | Select-Object OsName, CsName }
Remove-PSSession $session

# Verify connection was authenticated via Kerberos (not NTLM)
Get-WinEvent -LogName Security -FilterXPath `
    "*[System[EventID=4624] and EventData[Data[@Name='AuthenticationPackageName']='Kerberos']]" `
    -MaxEvents 5 | Select-Object TimeCreated, Message

Summary

Securing WinRM on Windows Server 2012 R2 requires migrating to HTTPS-only transport, disabling Basic and Digest authentication, restricting WinRM listener access to management network IP ranges, enabling comprehensive PowerShell script block logging, and deploying settings consistently via Group Policy. With these controls in place, remote management traffic is encrypted, credential exposure is minimized, and all PowerShell commands executed via WinRM are logged for forensic review. Combine WinRM hardening with Jump Server or PAW infrastructure to ensure that management traffic only originates from authorized, hardened endpoints.