Udostępnij przez


Wyliczanie WMI

Wyliczenie to czynność przechodzenia przez zestaw obiektów i ewentualnego modyfikowania każdego z nich po drodze. Można na przykład wyliczyć zestaw obiektów Win32_DiskDrive w celu znalezienia określonego numeru seryjnego. Należy pamiętać, że chociaż można wyliczać dowolny obiekt, usługa WMI zwraca tylko te obiekty, do których masz uprawnienia dostępu.

Wyliczenia dużych zestawów danych mogą wymagać dużej ilości zasobów i obniżyć wydajność. Aby uzyskać więcej informacji, zobacz Poprawa wydajności wyliczeń. Możesz również zażądać danych za pomocą bardziej szczegółowego zapytania. Aby uzyskać więcej informacji, zobacz Querying WMI.

W tym temacie omówiono następujące sekcje:

Wyliczanie WMI przy użyciu programu PowerShell

Jeśli nie znasz ścieżki obiektu dla określonego wystąpienia lub chcesz pobrać wszystkie wystąpienia dla określonej klasy, użyj Get-WmiObject, z nazwą klasy w parametrze -class. Jeśli chcesz użyć zapytania, możesz użyć parametru -query.

Poniższa procedura opisuje sposób wyliczania wystąpień klasy przy użyciu programu PowerShell.

Aby wyliczyć wystąpienia klasy przy użyciu programu PowerShell

  1. Wylicz wystąpienia za pomocą polecenia cmdlet Get-WmiObject.

    Get-WmiObject zwraca kolekcję co najmniej jednego obiektu WMI, które można enumerować. Aby uzyskać więcej informacji, zobacz Uzyskiwanie dostępu do kolekcji.

    Jeśli chcesz pobrać wystąpienie klasy WMI w innej przestrzeni nazw lub na innym komputerze, odpowiednio określ komputer i przestrzeń nazw w parametrach -computer i -namespace. Aby uzyskać więcej informacji, zobacz Tworzenie skryptu usługi WMI. Działa to tylko wtedy, gdy masz odpowiednie uprawnienia dostępu. Aby uzyskać więcej informacji, zobacz Obsługa Zabezpieczeń Usługi WMI i Wykonywanie Operacji Uprzywilejowanych.

  2. Pobierz dowolne indywidualne wystąpienia za pomocą elementów członkowskich kolekcji.

Poniższy przykład kodu pobiera kolekcję programu PowerShell, a następnie wyświetla właściwość size dla wszystkich wystąpień dysków logicznych na komputerze lokalnym.

$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." }
}

Wyliczanie WMI przy użyciu języka C# (Microsoft.Management.Infrastructure)

  1. Dodaj odwołanie do zestawu referencyjnego Microsoft.Management.Infrastructure. (Ten zestaw jest dostarczany jako część zestawu Windows Software Development Kit (SDK) dla systemu Windows 8.)
  2. Dodaj przy użyciu instrukcji dla przestrzeni nazw Microsoft.Management.Infrastructure.
    using Microsoft.Management.Infrastructure;
  1. Utwórz wystąpienie obiektu CimSession. Poniższy fragment kodu używa standardowej wartości "localhost" dla metody CimSession.Create.
    CimSession cimSession = CimSession.Create("localhost");
  1. Wywołaj metodę CimSession.QueryInstances przekazując żądaną przestrzeń nazw modelu CIM i WQL do użycia. Poniższy fragment kodu zwróci dwa wystąpienia reprezentujące dwa standardowe procesy systemu Windows, w których właściwość handle (reprezentująca identyfikator procesu lub PID) ma wartość 0 lub 4.
    IEnumerable<CimInstance> queryInstances =     
      cimSession.QueryInstances(@"root\cimv2", 
                                "WQL", 
                                @"select name from win32_process where handle = 0 or handle = 4");
  1. Przejdź przez zwrócone obiekty CimInstance.
    foreach (CimInstance cimInstance in enumeratedInstances)
    { 
      Console.WriteLine("Process name: {0}", cimInstance.CimInstanceProperties["Name"].Value);  
    }

Poniższy przykładowy kod wylicza wszystkie wystąpienia klasy Win32_Process (która reprezentuje aktywne procesy) na komputerze lokalnym i wyświetla nazwę każdego procesu.

Notatka

W rzeczywistej aplikacji należy zdefiniować jako parametry nazwę komputera ("localhost") i przestrzeń nazw CIM ("root\cimv2"). Dla uproszczenia zostały one zakodowane w tym przykładzie.

 

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("Enter WQL (x = Quit): ");
                string query = Console.ReadLine().ToUpper();
                if (query.CompareTo("X") == 0) break;
                MI.QueryInstance(query);
            }
        }
    }
}

Wyliczanie WMI przy użyciu C# (System.Management)

Jeśli nie znasz ścieżki obiektu dla określonego wystąpienia lub chcesz pobrać wszystkie wystąpienia określonej klasy, użyj obiektu ManagementClass, aby pobrać ManagementObjectCollection, który zawiera wszystkie wystąpienia danej klasy w przestrzeni nazw usługi WMI. Alternatywnie można wykonywać zapytania w usłudze WMI za pomocą ManagementObjectSearcher, aby uzyskać ten sam zestaw obiektów.

Notatka

System.Management była oryginalną przestrzenią nazw platformy .NET używaną do uzyskiwania dostępu do usługi WMI; jednak interfejsy API w tej przestrzeni nazw zwykle są wolniejsze i nie są skalowalne w stosunku do ich bardziej nowoczesnych odpowiedników w Microsoft.Management.Infrastructure.

 

Poniższa procedura opisuje sposób wyliczania wystąpień klasy przy użyciu języka C#.

Aby wyliczyć wystąpienia klasy przy użyciu języka C#

  1. Wyliczenie wystąpień za pomocą wywołania metody ManagementClass.GetInstances.

    Metoda GetInstances zwraca kolekcję lub zestaw obiektów, za pomocą których można wyliczyć. Aby uzyskać więcej informacji, zobacz Uzyskiwanie dostępu do kolekcji. Zwrócona kolekcja jest w rzeczywistości obiektem ManagementObjectCollection, więc można wywołać dowolną z metod tego obiektu.

    Jeśli chcesz pobrać wystąpienie klasy WMI w innej przestrzeni nazw lub na innym komputerze, określ komputer i przestrzeń nazw w parametrze ścieżki . Aby uzyskać więcej informacji, zobacz Tworzenie skryptu usługi WMI. Działa to tylko wtedy, gdy masz odpowiednie uprawnienia dostępu. Aby uzyskać więcej informacji, zobacz Obsługa zabezpieczeń usługi WMI i Wykonywanie Operacji Uprzywilejowanych.

  2. Pobierz dowolne wystąpienia, które chcesz, za pomocą elementów członkowskich kolekcji.

Poniższy przykład kodu pobiera kolekcję języka C#, a następnie wyświetla właściwość size dla wszystkich wystąpień dysków logicznych na komputerze lokalnym.

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

Wyliczanie obiektów WMI przy użyciu VBScript

Jeśli nie znasz ścieżki obiektu dla określonego wystąpienia lub jeśli chcesz pobrać wszystkie wystąpienia określonej klasy, użyj metody SWbemServices.InstancesOf, aby zwrócić wyliczenie SWbemObjectSet wszystkich wystąpień klasy. Alternatywnie możesz wykonać zapytanie w usłudze WMI za pomocą SWbemServices.ExecQuery, aby uzyskać ten sam zestaw obiektów.

Poniższa procedura opisuje sposób wyliczania wystąpień klasy przy użyciu języka VBScript.

Aby wyliczyć wystąpienia klasy przy użyciu języka VBScript

  1. Wyliczenie wystąpień za pomocą wywołania metody SWbemServices.InstancesOf.

    Metoda InstancesOf zwraca kolekcję lub zestaw obiektów, za pomocą których można wyliczyć. Aby uzyskać więcej informacji, zobacz Uzyskiwanie dostępu do kolekcji. Zwracana kolekcja jest w rzeczywistości obiektem SWbemObjectSet, więc można wywołać dowolną z metod tego obiektu.

    Jeśli chcesz pobrać wystąpienie klasy WMI w innej przestrzeni nazw lub na innym komputerze, określ komputer i przestrzeń nazw w moniker. Aby uzyskać więcej informacji, zobacz Tworzenie skryptu usługi WMI. Działa to tylko wtedy, gdy masz odpowiednie uprawnienia dostępu. Aby uzyskać więcej informacji, zobacz Zarządzanie bezpieczeństwem usługi WMI i Wykonywanie operacji uprzywilejowanych.

  2. Pobierz dowolne wystąpienia, które chcesz, korzystając z metod kolekcji.

Poniższy przykład kodu pobiera obiekt SWbemServices, a następnie wykonuje metodę InstancesOf, aby wyświetlić właściwość rozmiaru dla wszystkich wystąpień dysków logicznych na komputerze lokalnym.

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

Wyliczanie WMI przy użyciu C++

Oprócz wykonywania podstawowego wyliczenia można ustawić kilka flag i właściwości, aby zwiększyć wydajność wyliczania. Aby uzyskać więcej informacji, zobacz Poprawa wydajności enumeracji.

Aby wyliczyć zestaw obiektów w usłudze WMI

  1. Utwórz interfejs IEnumWbemClassObject opisujący zestaw obiektów, które chcesz wyliczyć.

    Obiekt IEnumWbemClassObject zawiera listę opisującą zestaw obiektów WMI. Można użyć metod IEnumWbemClassObject do wyliczania dalej, pomijania obiektów, rozpoczynania od początku i kopiowania modułu wyliczającego. W poniższej tabeli wymieniono metody używane do tworzenia modułów wyliczania dla różnych typów obiektów WMI.

    Obiekt Metoda
    Klasa
    IWbemServices::CreateClassEnum
    [IWbemServices::CreateClassEnumAsync](/windows/desktop/api/WbemCli/nf-wbemcli-iwbemservices-createclassenumasync)
    Instancja
    IWbemServices::CreateInstanceEnum
    [IWbemServices::CreateInstanceEnumAsync](/windows/desktop/api/WbemCli/nf-wbemcli-iwbemservices-createinstanceenumasync)
    Wynik zapytania
    IWbemServices::ExecQuery
    [IWbemServices::ExecQueryAsync](/windows/desktop/api/WbemCli/nf-wbemcli-iwbemservices-execqueryasync)
    Powiadomienie o zdarzeniu
    IWbemServices::ExecNotificationQuery
    [IWbemServices::ExecNotificationQueryAsync](/windows/desktop/api/WbemCli/nf-wbemcli-iwbemservices-execnotificationqueryasync)

     

  2. Przechodzenie przez zwrócone wyliczenie przy użyciu wielu wywołań do IEnumWbemClassObject::Next lub IEnumWbemClassObject::NextAsync.

Aby uzyskać więcej informacji, zobacz Manipulowanie informacjami o klasie i instancji.