简介
在企业环境中,经常需要利用闲置的 Windows 机器作为临时服务器,或者通过脚本远程调用程序、查看日志文件。Windows 内置的服务「WinRM」(Windows Remote Management)可以满足这一需求。
本文介绍如何使用 Windows 内置的 WinRM 服务配合 Python 的 pywinrm 库实现远程服务器控制。内容涵盖被控端 Windows 系统的服务启动、监听配置及客户端设置,以及控制端安装依赖、编写连接代码和执行命令的方法。同时补充了防火墙端口开放、安全性建议(如避免明文传输)及常见错误排查指南,帮助开发者安全高效地管理远程 Windows 环境。

在企业环境中,经常需要利用闲置的 Windows 机器作为临时服务器,或者通过脚本远程调用程序、查看日志文件。Windows 内置的服务「WinRM」(Windows Remote Management)可以满足这一需求。
WinRM 是一种基于简单对象访问协议(SOAP)的防火墙友好协议,允许来自不同供应商的硬件和操作系统进行互操作。它支持 PowerShell 远程执行,是管理远程 Windows 系统的标准方式之一。
以下以 Windows 10 或 Windows Server 系统为例,介绍如何配置被控端。
以管理员权限打开 CMD 或 PowerShell 命令窗口,输入以下命令启动 WinRM 服务:
winrm quickconfig -q
如果运行报错,提示网络类型设置异常,可以通过快捷键 Win+I 进入网络和 Internet 设置,更改网络配置文件,由'公用'切换为'专用'。
在命令行输入以下命令,查看 WinRM 服务的监听状态。注意记录端口号(Port),后续连接会用到。
winrm e winrm/config/listener
预期输出示例:
Listener
Address = *
Transport = HTTP
Port = 5985
Hostname
Enabled = true
URLPrefix = wsman
CertificateThumbprint
ListeningOn = **
默认情况下,HTTP 监听端口为 5985,HTTPS 为 5986。生产环境建议启用 HTTPS 以提高安全性。
为了允许非加密传输及基本认证(仅用于测试环境,生产环境请谨慎),需进行如下配置:
配置 Client:
winrm set winrm/config/client @{AllowUnencrypted="true"}
winrm set winrm/config/client @{TrustedHosts="*"}
winrm set winrm/config/client/auth @{Basic="true"}
配置 Service:
winrm set winrm/config/service @{AllowUnencrypted="true"}
winrm set winrm/config/service/auth @{Basic="true"}
配置完成后,可通过 winrm get winrm/config 验证配置是否生效。
确保 Windows 防火墙允许入站连接。通常 winrm quickconfig 会自动添加规则,但手动确认更稳妥。
在控制端(如 Mac OSX、Linux 或另一台 Windows),只需安装 pywinrm 依赖包即可。
pip install pywinrm
编写 Python 脚本连接 Windows 被控端。我们需要 IP 地址、端口号、用户名和密码。
import winrm
# 连接参数
host = "192.168.1.100"
port = 5985
username = "Administrator"
password = "your_password"
# 创建会话,transport 可选 'ntlm' 或 'basic'
session = winrm.Session(
f"http://{host}:{port}",
auth=(username, password),
transport='ntlm'
)
# 执行 CMD 命令
result = session.run_cmd('ipconfig', ['/all'])
print(result.status_code)
print(result.std_out.decode('utf-8'))
# 关闭会话
session.close()
为了便于维护,建议将逻辑封装为类,并处理编码问题及异常。
import winrm
import codecs
class WindowsRemoteManager:
def __init__(self, host, port, username, password):
self.host = host
self.port = port
self.session = winrm.Session(
f"http://{host}:{port}",
auth=(username, password),
transport='ntlm'
)
def run_cmd(self, cmd):
"""
执行 CMD 命令,获取返回值
:param cmd: 命令字符串
:return: 返回结果内容
"""
try:
result = self.session.run_cmd(cmd)
code = result.status_code
content = result.std_out if code == 0 else result.std_err
# 尝试 UTF-8 解码,失败则尝试 GBK
try:
return content.decode("utf-8")
except UnicodeDecodeError:
return content.decode("gbk")
except Exception as e:
return f"Error: {str(e)}"
def run_ps(self, cmd):
"""
执行 PowerShell 命令
:param cmd: 命令字符串
:return: 返回结果内容
"""
try:
result = self.session.run_ps(cmd)
code = result.status_code
content = result.std_out if code == 0 else result.std_err
try:
return content.decode("utf-8")
except UnicodeDecodeError:
return content.decode("gbk")
except Exception as e:
return f"Error: {str(e)}"
def close(self):
"""关闭会话"""
self.session.close()
# 使用示例
if __name__ == "__main__":
manager = WindowsRemoteManager(
host="192.168.1.100",
port=5985,
username="Administrator",
password="password"
)
# 查看 D 盘某日志文件内容
cmd = 'D: & cd py\\log & type trade.log'
output = manager.run_cmd(cmd)
print(output)
manager.close()
AllowUnencrypted="true" 和 Basic="true"。通过上述步骤,即可实现通过 Python 脚本安全、稳定地远程控制 Windows 服务器,自动化执行系统管理任务。

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online
将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online
通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online