You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过Python代码开启AWS Windows EC2的WSMan AllowUnencrypted解决pywinrm执行失败

解决方案:pywinrm连接AWS Windows EC2的配置问题

先解决SSL版本错误问题

你用https://访问5985端口是错误的——WinRM的5985是HTTP非加密端口,5986才是HTTPS加密端口。把endpoint的协议改成http://就能解决这个SSL错误:

protocol = Protocol(
    endpoint=f"http://{ec2_instance.public_dns_name}:5985/wsman",
    transport="ntlm",
    username="Administrator",
    password="Password",
    server_cert_validation="ignore",
)

核心需求:自动开启WinRM的AllowUnencrypted和Basic Auth

问题的本质是:如果不先配置这两个参数,pywinrm根本无法通过Basic auth连接实例执行命令。所以需要在实例可连接之前就完成配置,推荐两种方案:

方案1:EC2实例启动时用用户数据自动配置

创建EC2实例时,添加以下PowerShell用户数据,实例启动后会自动执行配置:

<powershell>
# 开启Basic认证
Set-Item -Force WSMan:\localhost\Service\auth\Basic $true
# 允许非加密连接
Set-Item -Force WSMan:\localhost\Service\AllowUnencrypted $true
# 重启WinRM服务使配置生效
Restart-Service WinRM
</powershell>

配置完成后,直接用Basic auth连接即可:

import winrm

session = winrm.Session(
    ec2_instance.public_dns_name,
    auth=(user_name, password),
    transport='basic',
    server_cert_validation='ignore'
)
result = session.run_ps("hostname")
print(result.std_out.decode('utf-8'))

方案2:用AWS SSM Run Command给已存在的实例配置

如果实例已经创建,不想重启,用AWS Systems Manager的Run Command远程执行配置脚本,无需手动登录实例。用boto3实现的示例代码:

import boto3
import time

ssm_client = boto3.client('ssm', region_name='你的AWS区域')
# 发送配置命令
response = ssm_client.send_command(
    InstanceIds=[ec2_instance.instance_id],
    DocumentName='AWS-RunPowerShellScript',
    Parameters={
        'commands': [
            'Set-Item -Force WSMan:\\localhost\\Service\\auth\\Basic $true',
            'Set-Item -Force WSMan:\\localhost\\Service\\AllowUnencrypted $true',
            'Restart-Service WinRM'
        ]
    }
)
# 等待命令执行完成
command_id = response['Command']['CommandId']
while True:
    invocation = ssm_client.get_command_invocation(
        CommandId=command_id,
        InstanceId=ec2_instance.instance_id
    )
    if invocation['Status'] in ['Success', 'Failed']:
        break
    time.sleep(5)

执行完成后,再用pywinrm的Basic auth或NTLM方式连接即可正常执行命令。

NTLM连接的正确示例

如果坚持使用NTLM,确认实例WinRM已开启NTLM认证(默认开启),使用以下代码:

from winrm.protocol import Protocol

protocol = Protocol(
    endpoint=f"http://{ec2_instance.public_dns_name}:5985/wsman",
    transport="ntlm",
    username="Administrator",
    password="Password",
    server_cert_validation="ignore",
)

# 执行命令流程
shell_id = protocol.open_shell()
command_id = protocol.run_command(shell_id, 'hostname')
std_out, std_err, status_code = protocol.get_command_output(shell_id, command_id)

print(f"输出:{std_out.decode('utf-8')}")
print(f"错误:{std_err.decode('utf-8')}")

# 清理资源
protocol.cleanup_command(shell_id, command_id)
protocol.close_shell(shell_id)

内容的提问来源于stack exchange,提问作者Praveen Tata

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 07:50:25