How to enable winrm in windows Part 1 — Enable WinRM on HTTP (port 5985) This is the easy part. Run PowerShell as Administrator on the Windows Server: powershell # One-shot configuration: starts the service, sets it to auto-start, # creates the HTTP listener on 5985, and opens the firewall rule. Enable-PSRemoting -Force That's it for HTTP. Verify: powershell # Should show a Transport=HTTP listener on port 5985 winrm enumerate winrm/config/Listener # Or with PowerShell cmdlets Get-WSManInstance -ResourceURI winrm/config/listener -Enumerate If the host is on a "Public" network profile , Enable-PSRemoting will refuse. Either change the profile to Private/Domain, or force it: powershell Enable-PSRemoting -Force -SkipNetworkProfileCheck Part 2 — Enable WinRM on HTTPS (port 5986) HTTPS requires a certificate. You have three options depending on your environment. Option A — Self-signed certificate (lab / quick test) powershell # 1) Create a self-signed cert. Use the server's real FQDN. $fqdn = [System.Net.Dns]::GetHostByName($env:COMPUTERNAME).HostName $cert = New-SelfSignedCertificate ` -DnsName $fqdn ` -CertStoreLocation Cert:\LocalMachine\My ` -KeyExportPolicy Exportable ` -KeySpec Signature ` -KeyLength 2048 ` -KeyAlgorithm RSA ` -HashAlgorithm SHA256 ` -NotAfter (Get-Date).AddYears(5) Write-Host "Thumbprint: $($cert.Thumbprint)" Write-Host "FQDN: $fqdn" # 2) Create the HTTPS listener bound to that cert New-Item -Path WSMan:\LocalHost\Listener ` -Transport HTTPS ` -Address * ` -CertificateThumbPrint $cert.Thumbprint ` -HostName $fqdn ` -Force # 3) Open the firewall for 5986 New-NetFirewallRule -DisplayName "WinRM HTTPS-In (TCP 5986)" ` -Direction Inbound ` -LocalPort 5986 ` -Protocol TCP ` -Action Allow ` -Profile Domain,Private Option B — Certificate from your enterprise CA (production) If you have an Active Directory Certificate Services CA, request a Server Authentication cert first: powershell # Request from AD CS using a template that allows Server Authentication # (the template name varies — common ones are "WebServer" or "Computer") $req = Get-Certificate ` -Template "WebServer" ` -DnsName $fqdn ` -SubjectName "CN=$fqdn" ` -CertStoreLocation Cert:\LocalMachine\My $cert = $req.Certificate # Then create the listener the same way as Option A, step 2+3 New-Item -Path WSMan:\LocalHost\Listener ` -Transport HTTPS ` -Address * ` -CertificateThumbPrint $cert.Thumbprint ` -HostName $fqdn ` -Force Option C — Existing certificate (you already have one) powershell # Find an existing Server Auth cert for this host $cert = Get-ChildItem Cert:\LocalMachine\My | Where-Object { $_.Subject -match $fqdn -and $_.EnhancedKeyUsageList.FriendlyName -contains "Server Authentication" } | Select-Object -First 1 # Use its thumbprint in step 2 of Option A Part 3 — Verify both listeners powershell # List all listeners; you should see two — HTTP on 5985 and HTTPS on 5986 winrm enumerate winrm/config/Listener Expected output (abbreviated): Listener Address = * Transport = HTTP Port = 5985 Enabled = true Listener Address = * Transport = HTTPS Port = 5986 Enabled = true CertificateThumbprint = A1B2C3D4... Test from the same server first (loopback check): powershell # HTTP Test-WSMan -ComputerName localhost # HTTPS — use -UseSSL and skip CA check if self-signed $opt = New-PSSessionOption -SkipCACheck -SkipCNCheck -SkipRevocationCheck Test-WSMan -ComputerName $fqdn -UseSSL -SessionOption $opt Then test from another machine on the network: powershell # From a different Windows box Test-WSMan -ComputerName dc01.corp.local Test-WSMan -ComputerName dc01.corp.local -UseSSL -SessionOption $opt Or from your Linux box with the Python script you already have: bash python winrm_ad_test.py --host dc01.corp.local --user 'CORP\admin' Part 4 — Hardening (recommended for production) After both listeners work, lock things down: powershell # Disable unencrypted traffic (forces NTLM/Kerberos encryption or HTTPS) Set-Item -Path WSMan:\LocalHost\Service\AllowUnencrypted -Value $false # Disable Basic auth (use NTLM/Kerberos/CredSSP instead) Set-Item -Path WSMan:\LocalHost\Service\Auth\Basic -Value $false # If you want to require HTTPS only, remove the HTTP listener Get-ChildItem WSMan:\LocalHost\Listener | Where-Object Keys -match "Transport=HTTP$" | Remove-Item -Recurse # Optional: restrict who can connect (default is BUILTIN\Administrators) Set-PSSessionConfiguration -Name Microsoft.PowerShell ` -ShowSecurityDescriptorUI For NTLM connections from non-domain Linux clients, you may also need to add the server to TrustedHosts on the client , not the server: powershell # On the Windows client (not needed for Linux pywinrm clients) Set-Item WSMan:\LocalHost\Client\TrustedHosts -Value "dc01.corp.local" -Force Part 5 — Rolling it out at scale via GPO For multiple servers, do it once via Group Policy instead of per-host: Computer Configuration → Policies → Administrative Templates → Windows Components → Windows Remote Management (WinRM) → WinRM Service Allow remote server management through WinRM → Enabled, IPv4/IPv6 filter = * Allow Basic authentication → Disabled Allow unencrypted traffic → Disabled And in Computer Configuration → Policies → Windows Settings → Security Settings → System Services , set Windows Remote Management (WS-Management) to Automatic. Firewall rule via GPO: Computer Configuration → Policies → Windows Settings → Security Settings → Windows Defender Firewall with Advanced Security → Inbound Rules → New Rule → Predefined → "Windows Remote Management" . The HTTPS cert is the only piece GPO can't easily push — that needs either AD CS auto-enrollment (recommended) or a per-host script. Common pitfalls The most frequent issues, in order of how often I've seen them bite people: the firewall rule existing but being scoped to "Private only" while the NIC is on a "Public" profile; the cert's CN/SAN not matching the hostname clients actually use (cert says dc01 but clients connect to dc01.corp.local ); the HTTPS listener pointing at a thumbprint whose cert has expired or been removed; and AllowUnencrypted=false combined with Basic auth, which leaves no working auth path. If Test-WSMan fails, check those four before anything else. Want me to put any of this into a single bootstrap PowerShell script you can drop onto a new server?