WMI の列挙

列挙とは、オブジェクトのセット内を移動し、移動しながら必要に応じて各オブジェクトを変更する動作です。 たとえば、Win32_DiskDrive オブジェクトのセットを列挙して、特定のシリアル番号を見つけることができます。 任意のオブジェクトを列挙できますが、WMI は、ユーザーがセキュリティ アクセス権を持っているオブジェクトのみを返します。

大規模なデータ セットの列挙では、大量のリソースが必要になり、パフォーマンスが低下する可能性があります。 詳細については、「列挙のパフォーマンスの向上」を参照してください。 より限定的なクエリを使用してデータを要求することもできます。 詳細については、「WMI のクエリ」を参照してください。

このトピックでは、以下のセクションについて説明します。

PowerShell を使用した WMI の列挙

特定のインスタンスのオブジェクト パスがわからない場合、または特定のクラスのすべてのインスタンスを取得する場合は、Get-WmiObject を使用し、クラスの名前を -class パラメーターに指定します。 クエリを使用する場合は、-query パラメーターを使用できます。

次の手順では、PowerShell を使用してクラスのインスタンスを列挙する方法について説明します。

PowerShell を使用してクラスのインスタンスを列挙するには

  1. Get-WmiObject コマンドレットを呼び出してインスタンスを列挙します。

    Get-WmiObject は、列挙できる 1 つ以上の WMI オブジェクトのコレクションを返します。 詳細については、コレクションへのアクセスに関する記事を参照してください。

    別の名前空間または別のコンピューターで WMI クラス インスタンスを取得する場合は、コンピューターと名前空間をそれぞれ -computer パラメーターと -namespace パラメーターで指定します。 詳細については、「WMI スクリプトの作成」を参照してください。 これは、ユーザーが適切なアクセス特権を持っている場合にのみ機能します。 詳細については、「WMI セキュリティの維持」と「特権操作の実行」を参照してください。

  2. コレクションのメンバーを使用して、任意の個々のインスタンスを取得します。

次のコード例では、PowerShell コレクションを取得し、ローカル コンピューター上の論理ドライブのすべてのインスタンスの size プロパティを表示します。

$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# を使用した WMI の列挙 (Microsoft.Management.Infrastructure)

  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. 使用する目的の CIM 名前空間と WQL を渡して CimSession.QueryInstances メソッドを呼び出します。 次のスニペットでは、(プロセス ID (PID) を表す) handle プロパティの値が 0 または 4 である 2 つの標準 Windows プロセスを表す 2 つのインスタンスを返します。
    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# を使用した WMI の列挙 (System.Management)

特定のインスタンスのオブジェクト パスがわからない場合、または特定のクラスのすべてのインスタンスを取得する場合は、ManagementClass オブジェクトを使用して、WMI 名前空間内の特定のクラスのすべてのインスタンスを含む ManagementObjectCollection を取得します。 または、ManagementObjectSearcher を使用して WMI に対してクエリを実行して、オブジェクトの同じセットを取得できます。

注意

System.Management は、WMI へのアクセスに使用される元の .NET 名前空間でした。ただし、この名前空間の API は一般に低速であり、より最新の Microsoft.Management.Infrastructure で対応する API に比べてスケーリングも行われません。

 

次の手順では、C# を使用してクラスのインスタンスを列挙する方法について説明します。

C# を使用してクラスのインスタンスを列挙するには

  1. ManagementClass.GetInstances を呼び出してインスタンスを列挙します。

    GetInstances メソッドは、列挙できるオブジェクトのコレクション (セット) を返します。 詳細については、コレクションへのアクセスに関する記事を参照してください。 返されるコレクションは実際には ManagementObjectCollection オブジェクトであるため、そのオブジェクトのメソッドのいずれかを呼び出すことができます。

    別の名前空間または別のコンピューターで WMI クラス インスタンスを取得する場合は、コンピューターと名前空間を path パラメーターで指定します。 詳細については、「WMI スクリプトの作成」を参照してください。 これは、ユーザーが適切なアクセス特権を持っている場合にのみ機能します。 詳細については、「WMI セキュリティの維持」と「特権操作の実行」を参照してください。

  2. コレクションのメンバーを使用して、任意の個々のインスタンスを取得します。

次のコード例では、C# コレクションを取得し、ローカル コンピューター上の論理ドライブのすべてのインスタンスの size プロパティを表示します。

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 クラス インスタンスを取得する場合は、コンピューターと名前空間をモニカーで指定します。 詳細については、「WMI スクリプトの作成」を参照してください。 これは、ユーザーが適切なアクセス特権を持っている場合にのみ機能します。 詳細については、「WMI セキュリティの維持」と「特権操作の実行」を参照してください。

  2. コレクション メソッドを使用して、任意の個々のインスタンスを取得します。

次のコード例では、SWbemServices オブジェクトを取得し、InstancesOf メソッドを実行して、ローカル コンピューター上の論理ドライブのすべてのインスタンスの size プロパティを表示します。

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::Next または IEnumWbemClassObject::NextAsync への複数の呼び出しを使用して、返された列挙を走査します。

詳細については、「クラスとインスタンスの情報の操作」を参照してください。