Aufzählen von WMI

Enumeration ist das Verschieben durch eine Reihe von Objekten und ggf. das Ändern der einzelnen Objekte. Beispielsweise können Sie einen Satz von Win32 _ DiskDrive-Objekten aufzählen, um eine bestimmte Seriennummer zu finden. Beachten Sie, dass WMI zwar ein beliebiges Objekt aufzählen kann, aber nur Objekte zurückgibt, auf die Sie Sicherheitszugriff haben.

Enumerationen großer Datensätze können eine große Menge an Ressourcen erfordern und die Leistung beeinträchtigen. Weitere Informationen finden Sie unter Verbessern der Enumerationsleistung. Sie können Daten auch mit einer spezifischeren Abfrage anfordern. Weitere Informationen finden Sie unter Abfragen von WMI.

In diesem Thema werden die folgenden Abschnitte erläutert:

Aufzählen von WMI mithilfe von PowerShell

Wenn Sie den Objektpfad für eine bestimmte Instanz nicht kennen oder alle Instanzen für eine bestimmte Klasse abrufen möchten, verwenden Sie Get-WmiObjectmit dem Namen der Klasse im -class-Parameter. Wenn Sie eine Abfrage verwenden möchten, können Sie den Parameter -query verwenden.

Im folgenden Verfahren wird beschrieben, wie die Instanzen einer Klasse mithilfe von PowerShell aufzählt werden.

So enumerieren Sie die Instanzen einer Klasse mithilfe von PowerShell

  1. Enumerieren Sie die Instanzen mit einem Aufruf des Cmdlets Get-WmiObject.

    Get-WmiObject gibt eine Auflistung von mindestens einem WMI-Objekt zurück, über das Sie aufzählen können. Weitere Informationen finden Sie unter Zugreifen auf eine Auflistung.

    Wenn Sie eine WMI-Klasseninstanz in einem anderen Namespace oder auf einem anderen Computer abrufen möchten, geben Sie den Computer und namespace in den Parametern -computer bzw. -namespace an. Weitere Informationen finden Sie unter Erstellen eines WMI-Skripts. Dies funktioniert nur, wenn Sie über die entsprechenden Zugriffsberechtigungen verfügen. Weitere Informationen finden Sie unter Verwalten der WMI-Sicherheit und Ausführen privilegierter Vorgänge.

  2. Rufen Sie alle einzelnen Instanzen ab, die Sie mit den Membern der Sammlung wünschen.

Im folgenden Codebeispiel wird eine PowerShell-Sammlung abgerufen und dann die Größeneigenschaft für alle Instanzen logischer Laufwerke auf dem lokalen Computer angezeigt.

$objCol = get-wmiobject -class "Win32_LogicalDisk"

# Or, alternately
#$objCol = get-wmiobject -Query "SELECT * FROM Win32_LogicalDisk"

foreach ($Drive in $objCol)
{
    if ($Drive.size -ne $null)
    { "Drive " + $Drive.deviceID + " contains " + $Drive.size + " bytes" }
    else
    { "Drive " + $Drive.deviceID + " is not available." }
}

Aufzählen von WMI mit C# (Microsoft.Management.Infrastructure)

  1. Fügen Sie einen Verweis auf die Verweis-Assembly Microsoft.Management.Infrastructure hinzu. (Diese Assembly wird als Teil des Windows Software Development Kit (SDK) für Windows 8.)
  2. Fügen Sie eine using-Anweisung für den Namespace Microsoft.Management.Infrastructure hinzu.
    using Microsoft.Management.Infrastructure;
  1. Instanziieren Sie ein CimSession-Objekt. Im folgenden Codeausschnitt wird der "localhost"-Standardwert für die CimSession.Create-Methode verwendet.
    CimSession cimSession = CimSession.Create("localhost");
  1. Rufen Sie die CimSession.QueryInstances-Methode auf, und übergeben Sie dabei den gewünschten CIM-Namespace und WQL. Der folgende Codeausschnitt gibt zwei -Instanzen zurück, die zwei standardmäßige Windows-Prozesse darstellen, wobei die Handleeigenschaft (die eine Prozess-ID oder PID darstellt) den Wert 0 oder 4 hat.
    IEnumerable<CimInstance> queryInstances =     
      cimSession.QueryInstances(@"root\cimv2", 
                                "WQL", 
                                @"select name from win32_process where handle = 0 or handle = 4");
  1. Schleife durch die zurückgegebenen CimInstance-Objekte.
    foreach (CimInstance cimInstance in enumeratedInstances)
    { 
      Console.WriteLine("Process name: {0}", cimInstance.CimInstanceProperties["Name"].Value);  
    }

Im folgenden Codebeispiel werden alle Instanzen der Win32 _ Process-Klasse (die aktive Prozesse darstellt) auf dem lokalen Computer aufzählt und den Namen der einzelnen Prozesse gedruckt.

Hinweis

In einer echten Anwendung würden Sie den Computernamen ("localhost") und den CIM-Namespace ("root \ cimv2") als Parameter definieren. Der Einfachheit halber wurden diese in diesem Beispiel hartcodiert.

using System;
using System.Collections.Generic;
using Microsoft.Management.Infrastructure;

public partial class MI
{
    static void PrintCimInstance(CimInstance cimInstance)
    {
        Console.ForegroundColor = ConsoleColor.Blue;
        Console.WriteLine("{0} properties", cimInstance.CimSystemProperties.ClassName);
        Console.ResetColor();

        Console.WriteLine(String.Format("{0,-5}{1,-30}{2,-15}{3,-10}", 
                                        "Key?", "Property", "Type", "Value"));

        foreach (var enumeratedProperty in cimInstance.CimInstanceProperties)
        {
            bool isKey = ((enumeratedProperty.Flags & CimFlags.Key) == CimFlags.Key);

            if (enumeratedProperty.Value != null)
            {
                Console.WriteLine(
                    "{0,-5}{1,-30}{2,-15}{3,-10}",
                    isKey == true ? "Y" : string.Empty,
                    enumeratedProperty.Name,
                    enumeratedProperty.CimType,
                    enumeratedProperty.Value);
            }
        }
        Console.WriteLine();
    }

    public static void QueryInstance(string query)
    {
        try
        {
            CimSession cimSession = CimSession.Create("localhost");

            IEnumerable<CimInstance> queryInstances = 
              cimSession.QueryInstances(@"root\cimv2", "WQL", query);
            foreach (CimInstance cimInstance in queryInstances)
            {
                //Use the current instance. This example prints the instance. 
                PrintCimInstance(cimInstance);
            }
        }
         catch (CimException ex) 
        { 
            // Handle the exception as appropriate.
            // This example prints the message.
            Console.WriteLine(ex.Message); 
        }
    }
}

using System;

namespace MIClientManaged
{
    class Program
    {
        static void Main(string[] args)
        {
            while (true)
            {
                Console.Write(&quot;Enter WQL (x = Quit): &quot;);
                string query = Console.ReadLine().ToUpper();
                if (query.CompareTo(&quot;X&quot;) == 0) break;
                MI.QueryInstance(query);
            }
        }
    }
}

Aufzählen von WMI mit C# (System.Management)

Wenn Sie den Objektpfad für eine bestimmte Instanz nicht kennen oder alle Instanzen für eine bestimmte Klasse abrufen möchten, verwenden Sie das ManagementClass-Objekt, um eine ManagementObjectCollection abzurufen, die alle Instanzen einer bestimmten Klasse im WMI-Namespace enthält. Alternativ können Sie WMI über managementObjectSearcher abfragen, um den gleichen Satz von Objekten zu erhalten.

Hinweis

System.Management war der ursprüngliche .NET-Namespace, der für den Zugriff auf WMI verwendet wurde. Die APIs in diesem Namespace sind jedoch im Allgemeinen langsamer und werden im Vergleich zu ihren moderneren Entsprechungen von Microsoft.Management.Infrastructure nicht so gut skaliert.

Im folgenden Verfahren wird beschrieben, wie die Instanzen einer Klasse mithilfe von C# aufzählt werden.

So enumerieren Sie die Instanzen einer Klasse mit C #

  1. Aufzählen der Instanzen mit einem Aufruf von ManagementClass.GetInstances.

    Die GetInstances-Methode gibt eine Auflistung oder einen Satz von -Objekten zurück, über die Sie aufzählen können. Weitere Informationen finden Sie unter Zugreifen auf eine Auflistung. Die zurückgegebene Auflistung ist tatsächlich ein ManagementObjectCollection-Objekt, sodass jede der Methoden dieses Objekts aufgerufen werden kann.

    Wenn Sie eine WMI-Klasseninstanz in einem anderen Namespace oder auf einem anderen Computer abrufen möchten, geben Sie den Computer und namespace im Path-Parameter an. Weitere Informationen finden Sie unter Erstellen eines WMI-Skripts. Dies funktioniert nur, wenn Sie über die entsprechenden Zugriffsberechtigungen verfügen. Weitere Informationen finden Sie unter Verwalten der WMI-Sicherheit und Ausführen privilegierter Vorgänge.

  2. Rufen Sie alle einzelnen Instanzen ab, die Sie mit den Membern der Sammlung wünschen.

Im folgenden Codebeispiel wird eine C#-Sammlung abgerufen und dann die Size-Eigenschaft für alle Instanzen logischer Laufwerke auf dem lokalen Computer angezeigt.

using System.Management;
...

ManagementClass mc = new ManagementClass("Win32_LogicalDisk");
ManagementObjectCollection objCol = mc.GetInstances();

//or, alternately
//ManagementObjectSearcher mgmtObjSearcher = new ManagementObjectSearcher("SELECT * FROM Win32_LogicalDisk");
//ManagementObjectCollection objCol = mgmtObjSearcher.Get();

if (objCol.Count != 0)
{
   foreach (ManagementObject Drive in objCol)
   {
      if (Drive["size"] != null)
      {
         Console.WriteLine("Drive {0} contains {1} bytes.", Drive["deviceID"], Drive["size"]);
      }
      else
      {
         Console.WriteLine("Drive {0} is not available.", Drive["deviceID"]);
      }
   }
}
Console.ReadLine();

Aufzählen von WMI mit VBScript

Wenn Sie den Objektpfad für eine bestimmte Instanz nicht kennen oder alle Instanzen für eine bestimmte Klasse abrufen möchten, verwenden Sie die SWbemServices.InstancesOf-Methode, um eine SWbemObjectSet-Enumeration aller Instanzen einer Klasse zurück zu geben. Alternativ können Sie WMI über SWbemServices.ExecQuery abfragen, um den gleichen Satz von Objekten zu erhalten.

Im folgenden Verfahren wird beschrieben, wie die Instanzen einer Klasse mit VBScript aufzählt werden.

So enumerieren Sie die Instanzen einer Klasse mit VBScript

  1. Aufzählen der Instanzen mit einem Aufruf der SWbemServices.InstancesOf-Methode.

    Die InstancesOf-Methode gibt eine Auflistung oder einen Satz von -Objekten zurück, über die Sie aufzählen können. Weitere Informationen finden Sie unter Zugreifen auf eine Auflistung. Die zurückgegebene Auflistung ist tatsächlich ein SWbemObjectSet-Objekt, sodass jede der Methoden dieses Objekts aufgerufen werden kann.

    Wenn Sie eine WMI-Klasseninstanz in einem anderen Namespace oder auf einem anderen Computer abrufen möchten, geben Sie den Computer und namespace im Moniker an. Weitere Informationen finden Sie unter Erstellen eines WMI-Skripts. Dies funktioniert nur, wenn Sie über die entsprechenden Zugriffsberechtigungen verfügen. Weitere Informationen finden Sie unter Verwalten der WMI-Sicherheit und Ausführen privilegierter Vorgänge.

  2. Rufen Sie mithilfe der Auflistungsmethoden alle einzelnen Instanzen ab, die Sie wünschen.

Im folgenden Codebeispiel wird ein SWbemServices-Objekt abgerufen und dann die InstancesOf-Methode ausgeführt, um die Size-Eigenschaft für alle Instanzen logischer Laufwerke auf dem lokalen Computer anzuzeigen.

Set objCol = GetObject("WinMgmts:").InstancesOf("Win32_LogicalDisk")
For Each Drive In objCol
    If Not IsNull(Drive.Size) Then    
       WScript.Echo ("Drive " & Drive.deviceid & " contains " & Drive.Size & " bytes")
    Else
       WScript.Echo ("Drive " & Drive.deviceid & " is not available.")
    End If
Next

Aufzählen von WMI mit C++

Zusätzlich zum Ausführen der grundlegenden Enumeration können Sie mehrere Flags und Eigenschaften festlegen, um die Leistung Ihrer Enumeration zu erhöhen. Weitere Informationen finden Sie unter Verbessern der Enumerationsleistung.

So enumerieren Sie einen Objektsatz in WMI

  1. Erstellen Sie eine IEnumWbemClassObject-Schnittstelle, die den Satz von Objekten beschreibt, die Sie aufzählen möchten.

    Ein IEnumWbemClassObject-Objekt enthält eine Liste, die einen Satz von WMI-Objekten beschreibt. Sie können die IEnumWbemClassObject-Methoden verwenden, um Vorwärts- und Überspringungsobjekte zu aufzählen, am Anfang zu beginnen und den Enumerator zu kopieren. In der folgenden Tabelle sind die Methoden aufgeführt, die zum Erstellen von Enumeratoren für verschiedene Typen von WMI-Objekten verwendet werden.

    Object Methode
    Klasse
    IWbemServices::CreateClassEnum

    [IWbemServices::CreateClassEnumAsync] (/windows/desktop/api/WbemCli/nf-wbemcli-iwbemservices-createclassenumasync)

    Instanz
    IWbemServices::CreateInstanceEnum
    [IWbemServices::CreateInstanceEnumAsync] (/windows/desktop/api/WbemCli/nf-wbemcli-iwbemservices-createinstanceenumasync)
    Abfrageergebnis
    IWbemServices::ExecQuery
    [IWbemServices::ExecQueryAsync] (/windows/desktop/api/WbemCli/nf-wbemcli-iwbemservices-execqueryasync)
    Ereignisbenachrichtigung
    IWbemServices::ExecNotificationQuery
    [IWbemServices::ExecNotificationQueryAsync] (/windows/desktop/api/WbemCli/nf-wbemcli-iwbemservices-execnotificationqueryasync)

    1. Durchlaufen Sie die zurückgegebene Enumeration mithilfe mehrerer Aufrufe von IEnumWbemClassObject::Next oder IEnumWbemClassObject::NextAsync.

    Weitere Informationen finden Sie unter Bearbeiten von Klassen- und Instanzinformationen.