Condividi tramite


Enumerazione WMI

L'enumerazione è l'atto di spostarsi attraverso un set di oggetti ed eventualmente di modificare ogni oggetto durante questa operazione. Ad esempio, è possibile enumerare tramite un set di oggetti Win32_DiskDrive per trovare un determinato numero di serie. Si noti che, sebbene sia possibile enumerare qualsiasi oggetto, WMI restituisce solo gli 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 Interrogare WMI.

Le sezioni seguenti sono descritte in questo argomento:

Enumerazione di 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 usando 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 computer diverso, specificare nei parametri -computer e -namespace rispettivamente il computer e lo spazio dei nomi. Per altre informazioni, vedere Creazione di uno script WMI. Questa operazione funziona solo se si dispone dei privilegi di accesso appropriati. Per ulteriori informazioni, vedere Mantenimento della sicurezza WMI e l'esecuzione di operazioni con privilegi.

  2. Recupera 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 del Windows Software Development Kit (SDK) per Windows 8.
  2. Aggiungere un usando istruzione 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 il namespace CIM desiderato e la 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 in ciclo 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 inseriti nel codice 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 ManagementObjectCollection che contiene tutte le istanze di una determinata classe nello spazio dei nomi WMI. In alternativa, è possibile eseguire query su WMI tramite un 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 generalmente più lente e non scalano altrettanto bene rispetto alle loro controparti più moderne in Microsoft.Management.Infrastructure.

 

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

Per enumerare le istanze di una classe con C#

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

    Il metodo GetInstances restituisce una raccolta 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 computer diverso, specificare il computer e lo spazio dei nomi nel parametro percorso . Per altre informazioni, vedere Creazione di uno script WMI. Questa operazione funziona solo se si dispone dei privilegi di accesso appropriati. Per ulteriori informazioni, vedere Mantenere la sicurezza WMI e Eseguire operazioni privilegiate.

  2. Recupera ogni singola istanza desiderata utilizzando i membri della raccolta.

Nell'esempio di codice seguente viene recuperata una raccolta C# e quindi viene mostrata la proprietà di dimensione 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 SWbemObjectSet'enumerazione 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 una raccolta o un set di oggetti tramite cui è possibile enumerare. Per ulteriori informazioni, vedere Accedere a una raccolta. L'insieme restituito è in realtà un oggetto SWbemObjectSet, quindi è possibile chiamare qualsiasi metodo dell'oggetto.

    Se si desidera recuperare un'istanza della classe WMI in un altro spazio dei nomi o in un computer diverso, 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 ulteriori informazioni, vedere Mantenimento della sicurezza WMI e Esecuzione di operazioni privilegiate.

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

Nell'esempio di codice seguente viene recuperato un oggettoSWbemServices 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 diversi tipi 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 maggiori informazioni, consultare Manipolazione delle informazioni su classi e istanze.