Enumerazione WMI

L'enumerazione è l'atto di spostarsi attraverso un set di oggetti e eventualmente di modificare ogni oggetto così come si fa. Ad esempio, è possibile enumerare tramite un set di oggetti Win32_DiskDrive per trovare un determinato numero di serie. Si noti che, anche se è possibile enumerare qualsiasi oggetto, WMI restituisce solo oggetti a cui si dispone dell'accesso alla sicurezza.

Le enumerazioni di set di dati di grandi dimensioni possono richiedere una grande quantità di risorse e ridurre le prestazioni. Per altre informazioni, vedere Miglioramento delle prestazioni di enumerazione. È anche possibile richiedere dati con una query più specifica. Per altre informazioni, vedere Esecuzione di query su WMI.

In questo argomento vengono illustrate le sezioni seguenti:

Enumerazione WMI tramite PowerShell

Se non si conosce il percorso dell'oggetto per un'istanza specifica o si desidera recuperare tutte le istanze per una classe specifica, usare Get-WmiObject, con il nome della classe nel parametro -class . Se si vuole usare una query, è possibile usare il parametro -query .

La procedura seguente descrive come enumerare le istanze di una classe usando PowerShell.

Per enumerare le istanze di una classe tramite PowerShell

  1. Enumerare le istanze con una chiamata al cmdlet Get-WmiObject .

    Get-WmiObject restituisce una raccolta di uno o più oggetti WMI, tramite cui è possibile enumerare. Per altre informazioni, vedere Accesso a una raccolta.

    Se si desidera recuperare un'istanza della classe WMI in un altro spazio dei nomi o in un altro computer, specificare rispettivamente il computer e lo spazio dei nomi nei parametri -computer e -namespace . Per altre informazioni, vedere Creazione di uno script WMI. Questa operazione funziona solo se si dispone dei privilegi di accesso appropriati. Per altre informazioni, vedere Gestione della sicurezza WMI e esecuzione di operazioni con privilegi.

  2. Recuperare tutte le singole istanze desiderate usando i membri della raccolta.

Nell'esempio di codice seguente viene recuperata una raccolta di PowerShell e quindi viene visualizzata la proprietà size per tutte le istanze di unità logiche nel computer locale.

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

Enumerazione WMI tramite C# (Microsoft.Management.Infrastructure)

  1. Aggiungere un riferimento all'assembly di riferimento Microsoft.Management.Infrastructure . Questo assembly viene fornito come parte di Windows Software Development Kit (SDK) per Windows 8.
  2. Aggiungere un'istruzione using per lo spazio dei nomi Microsoft.Management.Infrastructure .
    using Microsoft.Management.Infrastructure;
  1. Creare un'istanza di un oggetto CimSession . Il frammento di codice seguente usa il valore "localhost" standard per il metodo CimSession.Create .
    CimSession cimSession = CimSession.Create("localhost");
  1. Chiamare il metodo CimSession.QueryInstances passando lo spazio dei nomi CIM desiderato e WQL da usare. Il frammento di codice seguente restituirà due istanze che rappresentano due processi di Windows standard in cui la proprietà handle (che rappresenta un ID processo o PID) ha un valore pari a 0 o 4.
    IEnumerable<CimInstance> queryInstances =     
      cimSession.QueryInstances(@"root\cimv2", 
                                "WQL", 
                                @"select name from win32_process where handle = 0 or handle = 4");
  1. Scorrere gli oggetti CimInstance restituiti.
    foreach (CimInstance cimInstance in enumeratedInstances)
    { 
      Console.WriteLine("Process name: {0}", cimInstance.CimInstanceProperties["Name"].Value);  
    }

Nell'esempio di codice seguente vengono enumerate tutte le istanze della classe Win32_Process (che rappresenta i processi attivi) nel computer locale e viene stampato il nome di ogni processo.

Nota

In un'applicazione reale è necessario definire come parametri il nome del computer ("localhost") e lo spazio dei nomi CIM ("root\cimv2"). Ai fini della semplicità, questi sono stati hardcoded in questo esempio.

 

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

Enumerazione WMI tramite C# (System.Management)

Se non si conosce il percorso dell'oggetto per un'istanza specifica o si desidera recuperare tutte le istanze per una classe specifica, utilizzare l'oggetto ManagementClass per recuperare un Oggetto ManagementObjectCollection contenente tutte le istanze di una determinata classe nello spazio dei nomi WMI. In alternativa, è possibile eseguire query su WMI tramite managementObjectSearcher per ottenere lo stesso set di oggetti.

Nota

System.Management era lo spazio dei nomi .NET originale usato per accedere a WMI; Tuttavia, le API in questo spazio dei nomi sono in genere più lente e non vengono ridimensionate anche rispetto alle controparti Microsoft.Management.Infrastructure più moderne.

 

La procedura seguente descrive come enumerare le istanze di una classe usando C#.

Per enumerare le istanze di una classe usando C #

  1. Enumerare le istanze con una chiamata a ManagementClass.GetInstances.

    Il metodo GetInstances restituisce un insieme, o un set, di oggetti tramite cui è possibile enumerare. Per altre informazioni, vedere Accesso a una raccolta. L'insieme restituito è in realtà un oggetto ManagementObjectCollection , quindi è possibile chiamare qualsiasi metodo di tale oggetto.

    Se si desidera recuperare un'istanza della classe WMI in un altro spazio dei nomi o in un altro computer, specificare il computer e lo spazio dei nomi nel parametro path . Per altre informazioni, vedere Creazione di uno script WMI. Questa operazione funziona solo se si dispone dei privilegi di accesso appropriati. Per altre informazioni, vedere Gestione della sicurezza WMI e esecuzione di operazioni con privilegi.

  2. Recuperare tutte le singole istanze desiderate usando i membri della raccolta.

Nell'esempio di codice seguente viene recuperata una raccolta C# e quindi viene visualizzata la proprietà size per tutte le istanze di unità logiche nel computer locale.

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

Enumerazione WMI tramite VBScript

Se non si conosce il percorso dell'oggetto per un'istanza specifica o si desidera recuperare tutte le istanze per una classe specifica, utilizzare il metodo SWbemServices.InstancesOf per restituire un'enumerazione SWbemObjectSet di tutte le istanze di una classe. In alternativa, è possibile eseguire query su WMI tramite SWbemServices.ExecQuery per ottenere lo stesso set di oggetti.

La procedura seguente descrive come enumerare le istanze di una classe usando VBScript.

Per enumerare le istanze di una classe usando VBScript

  1. Enumerare le istanze con una chiamata al metodo SWbemServices.InstancesOf .

    Il metodo InstancesOf restituisce un insieme, o un set, di oggetti tramite cui è possibile enumerare. Per altre informazioni, vedere Accesso a una raccolta. L'insieme restituito è in realtà un oggetto SWbemObjectSet , quindi è possibile chiamare uno qualsiasi dei metodi di tale oggetto.

    Se si desidera recuperare un'istanza della classe WMI in un altro spazio dei nomi o in un altro computer, specificare il computer e lo spazio dei nomi nel moniker. Per altre informazioni, vedere Creazione di uno script WMI. Questa operazione funziona solo se si dispone dei privilegi di accesso appropriati. Per altre informazioni, vedere Gestione della sicurezza WMI e esecuzione di operazioni con privilegi.

  2. Recuperare tutte le singole istanze desiderate usando i metodi delle raccolte.

Nell'esempio di codice seguente viene recuperato un oggetto SWbemServices e quindi viene eseguito il metodo InstancesOf per visualizzare la proprietà size per tutte le istanze di unità logiche nel computer locale.

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

Enumerazione WMI con C++

Oltre a eseguire l'enumerazione di base, è possibile impostare diversi flag e proprietà per aumentare le prestazioni dell'enumerazione. Per altre informazioni, vedere Miglioramento delle prestazioni di enumerazione.

Per enumerare un set di oggetti in WMI

  1. Creare un'interfaccia IEnumWbemClassObject che descrive il set di oggetti da enumerare.

    Un oggetto IEnumWbemClassObject contiene un elenco che descrive un set di oggetti WMI. È possibile usare i metodi IEnumWbemClassObject per enumerare gli oggetti in avanti, ignorare gli oggetti, iniziare all'inizio e copiare l'enumeratore. Nella tabella seguente sono elencati i metodi usati per creare enumeratori per tipi diversi di oggetti WMI.

    Oggetto Metodo
    Classe
    IWbemServices::CreateClassEnum
    [IWbemServices::CreateClassEnumAsync] (/windows/desktop/api/WbemCli/nf-wbemcli-iwbemservices-createclassenumasync)
    Istanza
    IWbemServices::CreateInstanceEnum
    [IWbemServices::CreateInstanceEnumAsync] (/windows/desktop/api/WbemCli/nf-wbemcli-iwbemservices-createinstanceenumasync)
    Risultato della query
    IWbemServices::ExecQuery
    [IWbemServices::ExecQueryAsync] (/windows/desktop/api/WbemCli/nf-wbemcli-iwbemservices-execqueryasync)
    Notifica degli eventi
    IWbemServices::ExecNotificationQuery
    [IWbemServices::ExecNotificationQueryAsync] (/windows/desktop/api/WbemCli/nf-wbemcli-iwbemservices-execnotificationqueryasync)

     

  2. Attraversa l'enumerazione restituita usando più chiamate a IEnumWbemClassObject::Next o IEnumWbemClassObject::NextAsync.

Per altre informazioni, vedere Modifica delle informazioni sulla classe e sull'istanza.