2010-09-22 10 views
13

Me gustaría crear una pequeña aplicación que pueda recopilar información del sistema (Win32_blablabla) utilizando WinRM en lugar de WMI. ¿Cómo puedo hacer eso desde C#?Cómo acceder a WinRM en C#

El objetivo principal es utilizar WS-Man (WinRm) en lugar de DCOM (WMI).

Respuesta

13

Supongo que la manera más fácil sería usar la automatización WSMAN. wsmauto.dll referencia de windwos \ System32 en su proyecto:

alt text

entonces, código de abajo debería funcionar para usted. Descripción API está aquí: 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); 
    } 
} 

esperanza que esta ayuda, que se refiere a

1

me gustaría tener en cuenta que esto muestra un error de interoperabilidad de forma predeterminada en Visual Studio 2010.
compárese http://blogs.msdn.com/b/mshneer/archive/2009/12/07/interop-type-xxx-cannot-be-embedded-use-the-applicable-interface-instead.aspx

Parece haber dos formas de solucionar esto. Este primero está documentado en el artículo mencionado anteriormente y parece ser la forma correcta de manejar el problema. Los cambios pertinentes para este ejemplo son:

WSMan wsManObject = new WSMan(); Esto es en lugar de IWSMan wsman = new WSManClass(); que arrojará el error.

La segunda resolución es ir al VS2010-> Solution Explorer-> Solution-> Project-> References y seleccionar WSManAutomation. Haga clic derecho o presione Alt-Enter para acceder a las propiedades. Cambie el valor de la propiedad "Insertar tipos de interoperabilidad" de la referencia de wsmauto.

3

Tengo un artículo que describe una manera fácil de ejecutar Powershell a través de WinRM desde .NET en http://getthinktank.com/2015/06/22/naos-winrm-windows-remote-management-through-net/.

El código está en un solo archivo si solo desea copiarlo y también es un paquete NuGet que incluye la referencia a System.Management.Automation.

Gestiona automáticamente hosts de confianza, puede ejecutar bloques de scripts y también enviar archivos (lo cual no es realmente compatible, pero he creado una solución alternativa). Los retornos son siempre los objetos en bruto de 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); 

Espero que esto ayude, he estado usando esto por un tiempo con mis implementaciones automatizadas. Deje comentarios si encuentra problemas.

Cuestiones relacionadas