列舉 WMI

列舉是一組物件移動的動作,而且可能會像您一樣修改每個物件。 例如,您可以透過一組 Win32_DiskDrive 物件來列舉,以尋找特定的序號。 請注意,雖然您可以列舉任何物件,但 WMI 只會傳回您具有安全性存取權的物件。

大型資料集的列舉可能需要大量的資源並降低效能。 如需詳細資訊,請參閱 改善列舉效能。 您也可以使用更明確的查詢來要求資料。 如需詳細資訊,請參閱 查詢 WMI

本主題將討論下列各節:

使用 PowerShell 列舉 WMI

如果您不知道特定實例的物件路徑,或想要擷取特定類別的所有實例,請使用 Get-WmiObject搭配 -class 參數中的類別名稱。 如果您想要使用查詢,您可以使用 -query 參數。

下列程式描述如何使用 PowerShell 列舉類別的實例。

使用 PowerShell 列舉類別的實例

  1. 使用 呼叫 Get-WmiObject Cmdlet 列舉實例。

    Get-WmiObject 會傳回一或多個 WMI 物件的集合,您可以透過此集合進行列舉。 如需詳細資訊,請參閱 存取集合

    如果您想要在另一個命名空間或不同電腦上擷取 WMI 類別實例,請分別在 -computer-namespace 參數中指定電腦和命名空間。 如需詳細資訊,請參閱 建立 WMI 腳本。 只有在您具有適當的存取權限時,才能運作。 如需詳細資訊,請參閱維護 WMI 安全性和執行特殊許可權作業

  2. 使用集合的成員擷取您想要的任何個別實例。

下列程式碼範例會擷取 PowerShell 集合,然後顯示本機電腦上所有邏輯磁碟機實例的大小屬性。

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

使用 C# (Microsoft.Management.Infrastructure) 列舉 WMI

  1. 新增 Microsoft.Management.Infrastructure 參考元件的參考。 (此元件隨附于適用于 Windows 8.) 的Windows 軟體發展工具組 (SDK)
  2. Microsoft.Management.Infrastructure命名空間新增using語句。
    using Microsoft.Management.Infrastructure;
  1. 具現化 CimSession 物件。 下列程式碼片段使用 CimSession.Create 方法的標準 「localhost」 值。
    CimSession cimSession = CimSession.Create("localhost");
  1. 呼叫 CimSession.QueryInstances 方法,並傳遞要使用的所需 CIM 命名空間和 WQL。 下列程式碼片段會傳回兩個實例,代表兩個標準 Windows 進程,其中 handle 屬性 (代表進程識別碼,或 PID) 的 值為 0 或 4。
    IEnumerable<CimInstance> queryInstances =     
      cimSession.QueryInstances(@"root\cimv2", 
                                "WQL", 
                                @"select name from win32_process where handle = 0 or handle = 4");
  1. 迴圈查看傳回的 CimInstance 物件。
    foreach (CimInstance cimInstance in enumeratedInstances)
    { 
      Console.WriteLine("Process name: {0}", cimInstance.CimInstanceProperties["Name"].Value);  
    }

下列程式碼範例會列舉Win32_Process類別的所有實例, (代表本機電腦上 作用 中進程) ,並列印每個進程的名稱。

注意

在實際的應用程式中,您會將電腦名稱稱定義為電腦名稱稱 (「localhost」) 和 CIM 命名空間 (「root\cimv2」) 。 為了簡單起見,此範例已硬式編碼這些。

 

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

使用 C# (System.Management) 列舉 WMI

如果您不知道特定實例的物件路徑,或想要擷取特定類別的所有實例,請使用 ManagementClass 物件來擷取 ManagementObjectCollection ,其中包含 WMI 命名空間中指定類別的所有實例。 或者,您可以透過 ManagementObjectSearcher 查詢 WMI,以取得相同的物件集。

注意

System.Management 是用來存取 WMI 的原始 .NET 命名空間;不過,此命名空間中的 API 通常較慢,而且不會相對於其較新式 的 Microsoft.Management.Infrastructure 對應專案進行調整。

 

下列程式描述如何使用 C# 列舉類別的實例。

使用 C 列舉類別的實例#

  1. 列舉具有 ManagementClass.GetInstances 呼叫的實例。

    GetInstances方法會傳回您可以列舉的物件集合或集合。 如需詳細資訊,請參閱 存取集合。 傳回的集合實際上是 ManagementObjectCollection 物件,因此可以呼叫該物件的任何方法。

    如果您想要在另一個命名空間或不同電腦上擷取 WMI 類別實例,請在 path 參數中指定電腦和命名空間。 如需詳細資訊,請參閱 建立 WMI 腳本。 只有在您具有適當的存取權限時,才能運作。 如需詳細資訊,請參閱維護 WMI 安全性和執行特殊許可權作業

  2. 使用集合的成員擷取您想要的任何個別實例。

下列程式碼範例會擷取 C# 集合,然後顯示本機電腦上所有邏輯磁碟機實例的大小屬性。

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

使用 VBScript 列舉 WMI

如果您不知道特定實例的物件路徑,或想要擷取特定類別的所有實例,請使用 SWbemServices.InstancesOf 方法傳回類別所有實例的 SWbemObjectSet 列舉。 或者,您可以透過 SWbemServices.ExecQuery 查詢 WMI,以取得相同的物件集。

下列程式描述如何使用 VBScript 列舉類別的實例。

使用 VBScript 列舉類別的實例

  1. 列舉具有 SWbemServices.InstancesOf 方法呼叫的實例。

    InstancesOf方法會傳回您可以列舉的物件集合或集合。 如需詳細資訊,請參閱 存取集合。 傳回的集合實際上是 SWbemObjectSet 物件,因此可以呼叫該物件的任何方法。

    如果您想要在另一個命名空間或不同電腦上擷取 WMI 類別實例,請在 Moniker 中指定電腦和命名空間。 如需詳細資訊,請參閱 建立 WMI 腳本。 只有在您具有適當的存取權限時,才能運作。 如需詳細資訊,請參閱維護 WMI 安全性和執行特殊許可權作業

  2. 使用集合方法擷取您想要的任何個別實例。

下列程式碼範例會擷取 SWbemServices 物件,然後執行 InstancesOf 方法來顯示本機電腦上所有邏輯磁碟機實例的大小屬性。

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

使用 C++ 列舉 WMI

除了執行基本欄舉之外,您還可以設定數個旗標和屬性,以提高列舉的效能。 如需詳細資訊,請參閱 改善列舉效能

列舉 WMI 中的物件集

  1. 建立 IEnumWbemClassObject 介面,描述您想要列舉的物件集。

    IEnumWbemClassObject物件包含描述一組 WMI 物件的清單。 您可以使用 IEnumWbemClassObject 方法來列舉向前、略過物件、從開頭開始,以及複製列舉值。 下表列出用來為不同類型的 WMI 物件建立列舉值的方法。

    Object 方法
    類別
    IWbemServices::CreateClassEnum
    [IWbemServices::CreateClassEnumAsync] (/windows/desktop/api/WbemCli/nf-wbemcli-iwbemservices-createclassenumasync)
    執行個體
    IWbemServices::CreateInstanceEnum
    [IWbemServices::CreateInstanceEnumAsync] (/windows/desktop/api/WbemCli/nf-wbemcli-iwbemservices-createinstanceenumasync)
    查詢結果
    IWbemServices::ExecQuery
    [IWbemServices::ExecQueryAsync] (/windows/desktop/api/WbemCli/nf-wbemcli-iwbemservices-execqueryasync)
    事件通知
    IWbemServices::ExecNotificationQuery
    [IWbemServices::ExecNotificationQueryAsync] (/windows/desktop/api/WbemCli/nf-wbemcli-iwbemservices-execnotificationqueryasync)

     

  2. 使用對 IEnumWbemClassObject::NextIEnumWbemClassObject::NextAsync的多個呼叫來周遊傳回的列舉。

如需詳細資訊,請參閱 操作類別和實例資訊