WinRM 介绍与配置
发布日期
一、WinRM 介绍与配置指南
适用范围:Windows Server 2008 R2、2012/2012 R2、2016、2019、2022、2025,以及对应的 Windows 客户端系统。 本文重点介绍 WinRM 的基本原理、HTTP/HTTPS 配置步骤、认证方式、客户端连接和常见排障方法。
1. WinRM 是什么
WinRM(Windows Remote Management)是 Microsoft 对 WS-Management(WS-Man) 标准的实现,用于远程管理 Windows 主机。
WinRM 可以用于:
-
远程执行 PowerShell 命令
-
远程执行 CMD 命令
-
PowerShell Remoting
-
远程采集系统信息
-
查询服务、进程、事件日志、WMI/CIM 信息
-
自动化运维
-
配置管理
-
数据库服务器远程管理
常见调用方式包括:
-
PowerShell:
Enter-PSSession -
PowerShell:
Invoke-Command -
Windows:
winrs -
Windows:
winrm -
Python:
pywinrm -
Rust/Java/Go 等第三方 WS-Man/WinRM 库
2. WinRM 工作方式
WinRM 默认使用以下端口:
| 协议 | 默认端口 | 说明 |
|---|---|---|
| HTTP | TCP 5985 | WinRM HTTP |
| HTTPS | TCP 5986 | WinRM HTTPS |
典型结构:
客户端
│
│ WS-Man / WinRM
│
├── HTTP : 5985
│
└── HTTPS : 5986
│
▼
Windows WinRM Service
│
├── PowerShell
├── CMD
├── WMI
└── CIM
二、WinRM HTTP 和 HTTPS 配置的区别
3.1 HTTP
默认端口:
5985
典型地址:
http://192.168.1.100:5985/wsman
需要注意:
WinRM HTTP 并不意味着所有数据一定是明文。
如果使用:
- Kerberos
- NTLM
- Negotiate WinRM/WS-Man 可以利用认证协议提供的消息级加密保护数据。
但是:
Basic + HTTP
不推荐使用,因为 Basic 本身只是 Base64 编码用户名和密码。
3.2 HTTPS
默认端口:
5986
典型地址:
https://server01.example.com:5986/wsman
HTTPS 使用 TLS 对传输层进行加密。
适合:
- 非域环境
- Workgroup
- 使用 IP 访问
- 跨网络访问
- 对安全性要求较高的环境
三、WinRM 常见认证方式
WinRM 常见认证方式:
| 认证方式 | 域环境 | 非域环境 | 推荐程度 |
|---|---|---|---|
| Kerberos | 是 | 否 | 强烈推荐 |
| Negotiate | 是 | 是 | 推荐 |
| NTLM | 可以 | 可以 | 推荐用于非域 |
| Basic | 可以 | 可以 | 仅建议 HTTPS |
| CredSSP | 可以 | 可以 | 特殊场景 |
| Certificate | 可以 | 可以 | 高安全场景 |
推荐策略:
AD 域环境
↓
Kerberos + HTTP 5985
非域环境:
Workgroup
↓
NTLM / Negotiate
↓
优先 HTTPS 5986
四、检查 WinRM 当前运行状态
管理员 PowerShell:
Get-Service WinRM
或:
sc query WinRM
查看 Listener:
winrm enumerate winrm/config/listener
查看完整配置:
winrm get winrm/config
查看服务端认证配置:
winrm get winrm/config/service/auth
典型结果:
Auth
Basic = false
Kerberos = true
Negotiate = true
Certificate = false
CredSSP = false
五、HTTP (默认端口:5985) 配置
Step 1:确认网络类型
Windows Server 2012 及以上可以执行:
Get-NetConnectionProfile
如果网络类型是:
Public
建议改为:
Private
例如:
Set-NetConnectionProfile -InterfaceIndex 32 -NetworkCategory Private
再次检查:
Get-NetConnectionProfile
应看到:
NetworkCategory : Private
Windows Server 2008 R2 没有
Get-NetConnectionProfile/Set-NetConnectionProfile,需要通过网络和共享中心、防火墙配置或组策略处理。
Step 2:启用 WinRM
最通用的方法:
winrm quickconfig
也可以使用缩写:
winrm qc
系统会提示:
WinRM is not set up to receive requests on this machine.
确认执行:
y
也可以静默执行:
winrm quickconfig -quiet
Step 3:使用 PowerShell Remoting 配置
管理员 PowerShell:
Enable-PSRemoting -Force
该命令通常会完成:
-
启动 WinRM 服务
-
设置 WinRM 服务启动方式
-
创建 HTTP Listener
-
配置 PowerShell Remoting 对应防火墙规则
Step 4:检查 WinRM 服务
Get-Service WinRM
正常应为:
Status : Running
StartType: Automatic
如需手工配置:
Set-Service WinRM -StartupType Automatic
Start-Service WinRM
Step 5:检查 HTTP Listener
winrm enumerate winrm/config/listener
正常类似:
Listener
Address = *
Transport = HTTP
Port = 5985
Enabled = true
Step 6:确认端口监听
netstat -ano | findstr 5985
正常类似:
TCP 0.0.0.0:5985 0.0.0.0:0 LISTENING
TCP [::]:5985 [::]:0 LISTENING
Step 7:检查防火墙
较新的 Windows Server:
Get-NetFirewallRule |
Where-Object DisplayName -like "*WinRM*"
兼容性更好的命令:
netsh advfirewall firewall show rule name=all | findstr /i winrm
如果需要手工增加规则:
netsh advfirewall firewall add rule ^
name="WinRM HTTP 5985" ^
dir=in ^
action=allow ^
protocol=TCP ^
localport=5985
Step 8:服务端本机测试
Test-WSMan localhost
正常会返回类似:
wsmid
ProtocolVersion
ProductVendor
ProductVersion
Step 9:客户端连接
假设服务器:
IP:192.168.1.100
主机名:SERVER01
用户:Administrator
9.1 Windows 客户端测试端口
Test-NetConnection 192.168.1.100 -Port 5985
正常:
TcpTestSucceeded : True
9.2 测试 WS-Man
Test-WSMan 192.168.1.100
9.3 域环境
如果客户端和服务端在同一个 AD 域中:
Enter-PSSession `
-ComputerName SERVER01 `
-Credential DOMAIN\Administrator
通常会使用:
Kerberos
9.4 非域环境 / Workgroup
如果客户端和服务器不在域中,并且通过 IP 访问,需要在 Windows 客户端 设置 TrustedHosts。
例如:
Set-Item WSMan:\localhost\Client\TrustedHosts `
-Value "192.168.1.100"
查看:
Get-Item WSMan:\localhost\Client\TrustedHosts
多个服务器:
Set-Item WSMan:\localhost\Client\TrustedHosts `
-Value "192.168.1.100,192.168.1.101"
不建议生产环境使用:
Set-Item WSMan:\localhost\Client\TrustedHosts -Value "*"
9.5 使用本地管理员连接
$cred = Get-Credential
用户名建议写:
SERVER01\Administrator
然后:
Enter-PSSession `
-ComputerName 192.168.1.100 `
-Credential $cred
9.6 直接执行命令
Invoke-Command `
-ComputerName 192.168.1.100 `
-Credential $cred `
-ScriptBlock {
hostname
Get-Service WinRM
}
六、HTTPS (默认端口:5986) 配置
HTTPS 配置的核心步骤:
准备服务器证书
↓
证书安装到 LocalMachine\My
↓
创建 WinRM HTTPS Listener
↓
开放 TCP 5986
↓
客户端信任证书
↓
连接 WinRM HTTPS
6.1. HTTPS 证书要求
WinRM HTTPS Listener 使用的证书应满足:
-
包含私钥
-
存放于:
Cert:\LocalMachine\My
- 用途支持:
Server Authentication
-
证书未过期
-
证书名称应与客户端访问名称匹配
推荐:
CN = server01.example.com
SAN = server01.example.com
如果客户端使用 IP:
则建议 SAN 包含:
IPAddress=192.168.1.100
6.2. Windows Server 2012 R2 / 2016 及以上创建自签名证书
管理员 PowerShell:
$hostname = "SERVER01"
$cert = New-SelfSignedCertificate `
-DnsName $hostname `
-CertStoreLocation "Cert:\LocalMachine\My" `
-KeySpec KeyExchange `
-NotAfter (Get-Date).AddYears(2)
查看指纹:
$cert.Thumbprint
例如:
0123456789ABCDEF0123456789ABCDEF01234567
6.3. 使用 IP 创建证书
较新的 Windows Server 可以创建带 IP SAN 的证书:
$ip = "192.168.1.100"
$cert = New-SelfSignedCertificate `
-Type SSLServerAuthentication `
-Subject "CN=$ip" `
-CertStoreLocation "Cert:\LocalMachine\My" `
-KeySpec KeyExchange `
-TextExtension @(
"2.5.29.17={text}IPAddress=$ip"
) `
-NotAfter (Get-Date).AddYears(2)
检查:
$cert
6.4. Windows Server 2008 R2 的证书
Windows Server 2008 R2 默认环境通常没有现代版本的:
New-SelfSignedCertificate
因此更推荐:
-
使用企业 CA / AD CS 签发服务器证书
-
使用内部 CA
-
使用
certreq.exe创建 CSR 并签发证书
生产环境也建议优先使用 CA 签发证书,而不是长期使用自签名证书。
6.5. 创建 WinRM HTTPS Listener
先获取证书指纹:
Get-ChildItem Cert:\LocalMachine\My |
Select Subject, Thumbprint
假设:
Hostname = SERVER01
Thumbprint = 0123456789ABCDEF0123456789ABCDEF01234567
执行:
winrm create winrm/config/Listener?Address=*+Transport=HTTPS ^
@{Hostname="SERVER01";CertificateThumbprint="0123456789ABCDEF0123456789ABCDEF01234567"}
PowerShell 中也可以运行:
winrm create 'winrm/config/Listener?Address=*+Transport=HTTPS' `
'@{Hostname="SERVER01";CertificateThumbprint="0123456789ABCDEF0123456789ABCDEF01234567"}'
不同 PowerShell/CMD 对引号和转义处理不同。如果命令在 PowerShell 中解析异常,可直接在管理员 CMD 中执行。
6.6. winrm quickconfig -transport:https 是否会自动生成证书
不会。
命令:
winrm quickconfig -transport:https
可以帮助配置 HTTPS WinRM,但 不会自动生成服务器证书。
在执行该命令之前,服务器需要已经存在满足条件的证书。
如果没有合适证书,通常会报类似:
Cannot create a WinRM listener on HTTPS because this machine
does not have an appropriate certificate.
因此标准流程仍然是:
先创建 / 安装证书
↓
再配置 HTTPS Listener
6.7. 查看 HTTPS Listener
winrm enumerate winrm/config/listener
正常应看到两个 Listener:
Listener
Address = *
Transport = HTTP
Port = 5985
Listener
Address = *
Transport = HTTPS
Port = 5986
CertificateThumbprint = ...
6.8. 开放 HTTPS 5986 防火墙
netsh advfirewall firewall add rule ^
name="WinRM HTTPS 5986" ^
dir=in ^
action=allow ^
protocol=TCP ^
localport=5986
确认监听:
netstat -ano | findstr 5986
正常:
TCP 0.0.0.0:5986 0.0.0.0:0 LISTENING
6.9. HTTPS 服务端测试
Test-WSMan localhost -UseSSL
如果使用服务器名称:
Test-WSMan SERVER01 -UseSSL
HTTPS Windows 客户端连接
$cred = Get-Credential
然后:
Enter-PSSession `
-ComputerName SERVER01 `
-UseSSL `
-Credential $cred
远程执行:
Invoke-Command `
-ComputerName SERVER01 `
-UseSSL `
-Credential $cred `
-ScriptBlock {
hostname
Get-Service WinRM
}
自签名证书客户端信任
如果使用自签名证书,客户端默认通常不信任。
推荐将服务器证书或签发该证书的 CA 根证书导入客户端:
Trusted Root Certification Authorities
即:
受信任的根证书颁发机构 生产环境不建议长期依赖跳过证书校验。
七. macOS / Linux / python 测试 WinRM
macOS 和 Linux 不使用 Windows 的:
TrustedHosts
可以直接测试 TCP、HTTP/HTTPS 和 WinRM 认证。
7.1 测试 HTTP 5985
nc -vz 192.168.1.100 5985
7.2 测试 HTTPS 5986
nc -vz 192.168.1.100 5986
7.3 curl 测试 HTTP
curl -i http://192.168.1.100:5985/wsman
返回:
HTTP/1.1 401 Unauthorized
或者:
405 Method Not Allowed
通常说明 WinRM Listener 已经可以访问。
7.4 curl 测试 HTTPS
curl -k -i https://192.168.1.100:5986/wsman
-k仅用于测试,表示忽略 TLS 证书校验。
正式环境不建议使用。
7.5 macOS / Linux 使用 pywinrm
创建 Python 虚拟环境:
python3 -m venv ~/venv-winrm
source ~/venv-winrm/bin/activate
安装:
pip install pywinrm
HTTP方式连接测试
import winrm
session = winrm.Session(
'http://192.168.1.100:5985/wsman',
auth=('SERVER01\\Administrator', 'Password'),
transport='ntlm'
)
result = session.run_cmd('hostname')
print(result.status_code)
print(result.std_out.decode('gbk', errors='ignore'))
print(result.std_err.decode('gbk', errors='ignore'))
HTTPS方式连接测试
import winrm
session = winrm.Session(
'https://SERVER01:5986/wsman',
auth=('SERVER01\\Administrator', 'Password'),
transport='ntlm',
server_cert_validation='validate'
)
result = session.run_cmd('hostname')
print(result.status_code)
print(result.std_out.decode('gbk', errors='ignore'))
print(result.std_err.decode('gbk', errors='ignore'))
测试自签名证书时,可以临时:
server_cert_validation='ignore'
生产环境不建议这样使用。