如何在C#中访问WinRM

17

我想创建一个小应用程序,可以使用WinRM(而不是WMI)收集系统信息(Win32_blablabla)。如何在C#中实现这一点?

主要目标是使用WS-Man(WinRm)替代DCOM(WMI)。

3个回答

15

我猜最简单的方法是使用WSMAN自动化。在项目中引用windows\system32目录下的wsmauto.dll:

alt text

然后,下面的代码应该适用于您。API描述在这里:msdn: WinRM C++ API

IWSMan wsman = new WSManClass();
IWSManConnectionOptions options = (IWSManConnectionOptions)wsman.CreateConnectionOptions();                
if (options != null)
{
    try
    {
        // options.UserName = ???;  
        // options.Password = ???;  
        IWSManSession session = (IWSManSession)wsman.CreateSession("http://<your_server_name>/wsman", 0, options);
        if (session != null)
        {
            try
            {
                // retrieve the Win32_Service xml representation
                var reply = session.Get("http://schemas.microsoft.com/wbem/wsman/1/wmi/root/cimv2/Win32_Service?Name=winmgmt", 0);
                // parse xml and dump service name and description
                var doc = new XmlDocument();
                doc.LoadXml(reply);
                foreach (var elementName in new string[] { "p:Caption", "p:Description" })
                {
                    var node = doc.GetElementsByTagName(elementName)[0];
                    if (node != null) Console.WriteLine(node.InnerText);
                }
            }
            finally
            {
                Marshal.ReleaseComObject(session);
            }
        }
    }
    finally
    {
        Marshal.ReleaseComObject(options);
    }
}

希望这能帮到您,祝好


6
我有一篇文章,介绍了一种通过.NET从WinRM运行Powershell的简单方法,网址是http://getthinktank.com/2015/06/22/naos-winrm-windows-remote-management-through-net/。该代码为单文件形式,可以直接复制,也是NuGet包,其中包括对System.Management.Automation的引用。
它可以自动管理受信任的主机,可以运行脚本块,并且还可以发送文件(虽然这并不是真正支持的,但我创建了一个解决方法)。返回值始终是来自Powershell的原始对象。
// this is the entrypoint to interact with the system (interfaced for testing).
var machineManager = new MachineManager(
    "10.0.0.1",
    "Administrator",
    MachineManager.ConvertStringToSecureString("xxx"),
    true);

// will perform a user initiated reboot.
machineManager.Reboot();

// can run random script blocks WITH parameters.
var fileObjects = machineManager.RunScript(
    "{ param($path) ls $path }",
    new[] { @"C:\PathToList" });

// can transfer files to the remote server (over WinRM's protocol!).
var localFilePath = @"D:\Temp\BigFileLocal.nupkg";
var fileBytes = File.ReadAllBytes(localFilePath);
var remoteFilePath = @"D:\Temp\BigFileRemote.nupkg";
machineManager.SendFile(remoteFilePath, fileBytes);

希望这能帮到你,我一直在使用这个自动化部署的工具。如果你发现问题,请留下评论。

2
我想指出,在Visual Studio 2010中,默认情况下会显示一个Interop错误。参见:http://blogs.msdn.com/b/mshneer/archive/2009/12/07/interop-type-xxx-cannot-be-embedded-use-the-applicable-interface-instead.aspx 解决此问题似乎有两种方法。第一种方法在上述文章中有所记录,看起来是处理该问题的正确方式。本例中的相关更改为:
WSMan wsManObject = new WSMan(); 这代替了IWSMan wsman = new WSManClass();,后者将会抛出错误。
第二种解决方法是进入VS2010->解决方案资源管理器->解决方案->项目->引用,并选择WSManAutomation。右键单击或按Alt-Enter访问属性。更改wsmauto引用的“嵌入互操作类型”属性的值。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接