2010-05-27 24 views
12

me encontré con este código en un viejo hilo de apagar la máquina local:WMI para reiniciar la máquina remota

using System.Management; 

void Shutdown() 
{ 
    ManagementBaseObject mboShutdown = null; 
    ManagementClass mcWin32 = new ManagementClass("Win32_OperatingSystem"); 
    mcWin32.Get(); 

    // You can't shutdown without security privileges 
    mcWin32.Scope.Options.EnablePrivileges = true; 
    ManagementBaseObject mboShutdownParams = 
      mcWin32.GetMethodParameters("Win32Shutdown"); 

    // Flag 1 means we want to shut down the system. Use "2" to reboot. 
    mboShutdownParams["Flags"] = "1"; 
    mboShutdownParams["Reserved"] = "0"; 
    foreach (ManagementObject manObj in mcWin32.GetInstances()) 
    { 
     mboShutdown = manObj.InvokeMethod("Win32Shutdown", 
             mboShutdownParams, null); 
    } 
} 

¿Es posible utilizar un método de WMI similar a reiniciar la bandera de "2" una máquina remota, para lo cual solo tengo el nombre de la máquina, no la dirección IP.

EDIT: Actualmente tiene:

SearchResultCollection allMachinesCollected = machineSearch.FindAll(); 
Methods myMethods = new Methods(); 
string pcName; 
ArrayList allComputers = new ArrayList(); 
foreach (SearchResult oneMachine in allMachinesCollected) 
{ 
    //pcName = oneMachine.Properties.PropertyNames.ToString(); 
    pcName = oneMachine.Properties["name"][0].ToString(); 
    allComputers.Add(pcName); 
    MessageBox.Show(pcName + "has been sent the restart command."); 
    Process.Start("shutdown.exe", "-r -f -t 0 -m \\" + pcName); 
} 

pero esto no funciona, y yo preferiría WMI en el futuro.

Respuesta

14

Para direccionar las consultas WMI a una computadora remota, simplemente especifique el nombre (o la dirección IP) de esa computadora en el objeto ManagementScope.

No estoy bien en C#, pero aquí hay un ejemplo que surgió usando MSDN y WMI Code Creator (que es, por cierto, una excelente herramienta para generar código WMI, y admite C# entre otros). Espero que este código te dé la idea.

(responsabilidad:. Este código no se ha probado)

using System; 
using System.Management; 
... 

void Shutdown() 
{ 
    try 
    { 
     const string computerName = "COMPUTER"; // computer name or IP address 

     ConnectionOptions options = new ConnectionOptions(); 
     options.EnablePrivileges = true; 
     // To connect to the remote computer using a different account, specify these values: 
     // options.Username = "USERNAME"; 
     // options.Password = "PASSWORD"; 
     // options.Authority = "ntlmdomain:DOMAIN"; 

     ManagementScope scope = new ManagementScope(
      "\\\\" + computerName + "\\root\\CIMV2", options); 
     scope.Connect(); 

     SelectQuery query = new SelectQuery("Win32_OperatingSystem"); 
     ManagementObjectSearcher searcher = 
      new ManagementObjectSearcher(scope, query); 

     foreach (ManagementObject os in searcher.Get()) 
     { 
      // Obtain in-parameters for the method 
      ManagementBaseObject inParams = 
       os.GetMethodParameters("Win32Shutdown"); 

      // Add the input parameters. 
      inParams["Flags"] = 2; 

      // Execute the method and obtain the return values. 
      ManagementBaseObject outParams = 
       os.InvokeMethod("Win32Shutdown", inParams, null); 
     } 
    } 
    catch(ManagementException err) 
    { 
     MessageBox.Show("An error occurred while trying to execute the WMI method: " + err.Message); 
    } 
    catch(System.UnauthorizedAccessException unauthorizedErr) 
    { 
     MessageBox.Show("Connection error (user name or password might be incorrect): " + unauthorizedErr.Message); 
    } 
} 
+2

Como referencia, las "banderas" valor de 2 es lo que convierte esta solicitud de apagado en un reinicio. Lista completa de indicadores aquí: https://msdn.microsoft.com/en-us/library/aa394058(v=vs.85).aspx – Ceilingfish

4

Tuve problemas con esto también. WMI puede ser engañoso con métodos para clases y objetos. Mi solución es para reiniciar un host en la red con C# y WMI, pero es fácilmente simplificado para la máquina local:

private void rebootHost(string hostName) 
{ 
    string adsiPath = string.Format(@"\\{0}\root\cimv2", hostName); 
    ManagementScope scope = new ManagementScope(adsiPath); 
    // I've seen this, but I found not necessary: 
    // scope.Options.EnablePrivileges = true; 
    ManagementPath osPath = new ManagementPath("Win32_OperatingSystem"); 
    ManagementClass os = new ManagementClass(scope, osPath, null); 

    ManagementObjectCollection instances; 
    try 
    { 
     instances = os.GetInstances(); 
    } 
    catch (UnauthorizedAccessException exception) 
    { 
     throw new MyException("Not permitted to reboot the host: " + hostName, exception); 
    } 
    catch (COMException exception) 
    { 
     if (exception.ErrorCode == -2147023174) 
     { 
      throw new MyException("Could not reach the target host: " + hostName, exception); 
     } 
     throw; // Unhandled 
    } 
    foreach (ManagementObject instance in instances) 
    { 
     object result = instance.InvokeMethod("Reboot", new object[] { }); 
     uint returnValue = (uint)result; 

     if (returnValue != 0) 
     { 
      throw new MyException("Failed to reboot host: " + hostName); 
     } 
    } 
} 
+0

Encontré que este método funciona en máquinas virtuales Azure siempre que la máquina esté en el mismo VPN. La respuesta aceptada no lo hizo por alguna razón. – user3841460

0

esto funcionará como Sharm

gwmi win32_operatingsystem -ComputerName xxxxxxxxxxxx | Invoke-WmiMethod -Name reboot 
Cuestiones relacionadas