Windows 远程管理 (WinRM)问题详解包括c#与python例子

发布于:2025-08-07 ⋅ 阅读:(20) ⋅ 点赞:(0)

什么WinRM

        WinRM 是微软的远程管理协议,广泛用于执行远程命令和管理远程系统,类似于linux中的ssh。

如何开启WinRM

在远程机器上进行以下设置        

1.开启windows remote management服务并设置为自动启动,执行以下powershell(管理员运行)命令:

Start-Service winrm
Set-Service winrm -StartupType Automatic

2.开启powershell远程控制权限,执行以下powershell(管理员运行)命令:

Enable-PSRemoting -Force

备注:该命令会自动创建相应的防火墙规则开放相应的端口

3.允许基本身份认证和非加密连接,执行以下cmd命令(也是管理员运行,非powershell):

winrm set winrm/config/service/auth @{Basic="true"}
winrm set winrm/config/service @{AllowUnencrypted="true"}

备注:因为我的场景对安全性无任何要求,所以无需https加密连接。

测试WinRM连接

要测试WinRM是否成功配置,最简单的方法就是使用powershell对远程机器发出命令。

假如远程机器的ip为192.168.1.112,想要列出其桌面下的所有文件。可在本地机器上打开powershell,执行以下命令:

Invoke-Command -ComputerName 192.168.1.112 -ScriptBlock {  Get-ChildItem -Path "C:\Users\ken\Desktop" } -Credential (Get-Credential)

如下图所示:

备注:在这一步中,极有可能会出错,具体解决过程可参考后面内容。

如果成功执行,即会返回远程主机桌面上相应的文件列表,如下图所示:

备注:上述命令中的IP地址和桌面路径(主要是Users\后面的用户名不同)因人而异,请作相应的修改。 

代码调用

C#中调用

这里我使用的是.net 8.0,这里要安装两个Nuget包,分别是:

Microsoft.Management.Infrastructure {3.0.0}

System.Management.Automation        {7.3.7}  

如下图所示:

具体代码如下:

using System.Collections.ObjectModel;
using System.Management.Automation.Runspaces;
using System.Management.Automation;
using System.Security;

namespace DemoWinRM
{
    internal class Program
    {
        static void Main(string[] args)
        {
            Demo2();
        }
     
        static void Demo2()
        {
            // 请修改为正确的连接信息
            var remoteComputer = "192.168.1.112";
            var userName = "ken";
            var password = "1234566666";
            var command = "Get-ChildItem -Path \"C:\\Users\\ken\\Desktop\"";

            WSManConnectionInfo connectionInfo = new WSManConnectionInfo();
            connectionInfo.ComputerName = remoteComputer;
            connectionInfo.Credential = new PSCredential(userName, ConvertToSecureString(password));

            using (Runspace runspace = RunspaceFactory.CreateRunspace(connectionInfo))
            {
                runspace.Open();

                using (PowerShell ps = PowerShell.Create())
                {
                    ps.Runspace = runspace;
                    ps.AddScript(command);

                    Collection<PSObject> results = ps.Invoke();          

                    foreach (var result in results)
                    {
                        Console.WriteLine(result);
                    }
                }
            }
        }

        static SecureString ConvertToSecureString(string password)
        {
            SecureString secureString = new SecureString();

            foreach (char c in password)
            {
                secureString.AppendChar(c);
            }

            secureString.MakeReadOnly();

            return secureString;
        }
    }
}

运行结果如下:

python中调用

这里我使用是的python3.11,要先安装winrm模块:

pip install pywinrm

具体代码如下:

import winrm


def run():
    hostname = '192.168.1.112'
    username = 'ken'
    password = '1234566666'
    command = 'powershell -Command "Get-ChildItem -Path \"C:\\Users\\ken\\Desktop\""'

    # 输出结果中有文时,编码无论怎么改都好像有问题(感觉是这个库的一个BUG)
    session = winrm.Session(hostname, auth=(username, password))
    response = session.run_ps(command)
    print(response.std_out.decode('gbk'))  # 无论是cp1252, gbk, utf-8等都有问题


if __name__ == '__main__':
    run()


运行结果如下(这里的乱码问题请暂时忽略):

问题排查与解决

(1) [192.168.1.112] 连接到远程服务器 192.168.1.112 失败,并显示以下错误消息: WinRM 客户端无法处理该请求。如果身份验证方案与
 Kerberos 不同,或者客户端计算机未加入到域中, 则必须使用 HTTPS 传输或者必须将目标计算机添加到 TrustedHosts 配置设置。

如下图所示:

解决办法,在客户端(本地)计算机中,将ip 192.168.1.112加入到可信任主机配置即可,在powershell下(管理员)执行以下命令:

Set-Item WSMan:\localhost\Client\TrustedHosts -Value "192.168.1.112" -Force

(2) 在上述命令将ip加入到可信任主机配置时,可能也会报错,即:Set-Item : 客户端无法连接到请求中指定的目标。 请验证该目标上的服务是否正在运行以及是否正在接受请求。 有关目标(通常是 II
S 或 WinRM)上运行的 WS 管理服务,请查阅日志和文档。 如果目标是 WinRM 服务,则在目标上运行以下命令来分析和配置 WinRM 服
务: "winrm quickconfig"。

如下图所示:

这个问题也好解决,在客户端上重启一下winrm服务,然后重新执行上述命令(管理员执行)即可:

Restart-Service winrm
Set-Item WSMan:\localhost\Client\TrustedHosts -Value "192.168.1.112" -Force

如下图所示:

参考

Windows 远程管理 - Win32 apps | Microsoft Learn

使用 WinRM 进行 PowerShell 远程处理的安全注意事项 - PowerShell | Microsoft Learn

使用 C# 远程连接到 WMI - Win32 apps | Microsoft Learn

走进winrm ---powershell远程连接的4个安全级别,详解 - PowerShell免费软件 - 博客园


网站公告

今日签到

点亮在社区的每一天
去签到