2010-05-27 9 views
12

ich diesen Code auf einem alten Thread zur Abschaltung der lokale Maschine gefunden:WMI Remote-Computer neu zu starten

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); 
    } 
} 

Ist es möglich, Flag „2“, um einen Remote-Rechner eine ähnliche WMI-Methode zu verwenden, um neu zu starten, für die ich habe nur Maschinenname, nicht IPaddress.

EDIT: Ich habe zur Zeit:

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); 
} 

aber dies nicht funktioniert, und ich würde WMI vorwärts gehen bevorzugen.

Antwort

14

Um WMI-Abfragen an einen Remotecomputer zu adressieren, geben Sie einfach den Namen (oder die IP-Adresse) des Computers im Objekt ManagementScope an.

Ich bin nicht gut in C#, aber hier ist ein Beispiel, das ich mit MSDN und WMI Code Creator (das ist übrigens ein hervorragendes Werkzeug zum Generieren von WMI-Code und unterstützt C# unter anderem) kam. Hoffe, dieser Code wird dir die Idee geben.

(Haftungsausschluss:. Dieser Code ist nicht getestet)

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

Als Referenz arbeiten, die „Flags“ Wert 2 macht diese Abschaltanforderung zu einem Neustart. Vollständige Liste der Flags hier: https://msdn.microsoft.com/en-us/library/aa394058(v=vs.85).aspx – Ceilingfish

4

Ich hatte auch Probleme damit. WMI kann mit Methoden für Klassen und Objekt irreführen. Meine Lösung ist ein Host im Netzwerk mit C# und WMI für einen Neustart, aber leicht für die lokale Maschine vereinfacht:

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

Ich fand diese Methode funktioniert auf Azure VMs, solange die Maschine auf dem gleichen ist VPN. Die akzeptierte Antwort hat es aus irgendeinem Grund nicht getan. – user3841460

0

dies wie sharm

gwmi win32_operatingsystem -ComputerName xxxxxxxxxxxx | Invoke-WmiMethod -Name reboot 
Verwandte Themen