Recupero di parte di un'istanza WMI

Un recupero di istanza parziale è quando WMI recupera solo un subset delle proprietà di un'istanza. Ad esempio, WMI potrebbe recuperare solo le proprietà Name e Key . L'uso più comune del recupero di istanze parziali è in enumerazioni di grandi dimensioni con più proprietà.

Recupero di una parte di un'istanza WMI con PowerShell

È possibile recuperare una singola proprietà di un'istanza usando Get-WmiObject; la proprietà stessa può essere recuperata e visualizzata in diversi modi. Come per il recupero di un'istanza, PowerShell restituirà per impostazione predefinita tutte le istanze di una determinata classe; è necessario specificare un valore specifico se si desidera recuperare solo una singola istanza.

Nell'esempio di codice seguente viene visualizzato il numero di serie del volume per un'istanza della classe Win32_LogicalDisk .

(Get-WmiObject -class Win32_logicalDisk).DeviceID

#or

Get-WmiObject -class Win32_LogicalDisk | format-list DeviceID

#or

$myDisk = Get-WmiObject -class Win32_LogicalDisk
$myDisk.DeviceID

Recupero di una parte di un'istanza WMI usando C# (System.Management)

È possibile recuperare una singola proprietà di un'istanza creando un nuovo Oggetto ManagementObject usando i dettagli di un'istanza specifica. È quindi possibile recuperare in modo implicito una o più proprietà dell'istanza con il metodo GetPropertyValue .

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 sono più lente rispetto alle loro controparti Microsoft.Management.Infrastructure più moderne.

Nell'esempio di codice seguente viene visualizzato il numero di serie del volume per un'istanza della classe Win32_LogicalDisk .

using System.Management;
...
ManagementObject myDisk = new ManagementObject("Win32_LogicalDisk.DeviceID='C:'");
string myProperty = myDisk.GetPropertyValue("VolumeSerialNumber").ToString();
Console.WriteLine(myProperty);

Recupero di una parte di un'istanza WMI con VBScript

È possibile recuperare una singola proprietà di un'istanza usando GetObject.

Nell'esempio di codice seguente viene visualizzato il numero di serie del volume per un'istanza della classe Win32_LogicalDisk .

MsgBox (GetObject("WinMgmts:Win32_LogicalDisk='C:'").VolumeSerialNumber)

Recupero di una parte di un'istanza WMI con C++

La procedura seguente viene usata per richiedere un recupero parziale dell'istanza usando C++.

Per richiedere un recupero di istanza parziale con C++

  1. Creare un oggetto IWbemContext con una chiamata a CoCreateInstance.

    Un oggetto context è un oggetto che WMI usa per passare altre informazioni a un provider WMI. In questo caso si usa l'oggetto IWbemContext per indicare al provider di elaborare un recupero di istanza parziale.

  2. Aggiungere __GET_EXTENSIONS, __GET_EXT_CLIENT_REQUEST e altri valori denominati che descrivono le proprietà da recuperare nell'oggetto IWbemContext .

    Nella tabella seguente sono elencati i diversi valori denominati usati nella chiamata di recupero.

    Valore denominato Descrizione
    __GET_EXTENSIONS
    VT_BOOL impostata su VARIANT_TRUE. Usato per segnalare che vengono usate operazioni di recupero di istanze parziali. Ciò consente un controllo singolo rapido senza dover enumerare l'intero oggetto contesto. Se vengono usati uno degli altri valori, questo deve essere.
    __GET_EXT_PROPERTIES
    SAFEARRAY delle stringhe che elencano le proprietà da recuperare. Impossibile specificare contemporaneamente __GET_EXT_KEYS_ONLY.
    Un asterisco "*" è un nome di proprietà non valido per __GET_EXT_PROPERTIES.
    __GET_EXT_KEYS_ONLY
    VT_BOOL impostata su VARIANT_TRUE. Indica che è necessario specificare solo le chiavi nell'oggetto restituito. Impossibile specificare contemporaneamente __GET_EXT_PROPERTIES. Invece, ha la precedenza su __GET_EXT_PROPERTIES.
    __GET_EXT_CLIENT_REQUEST
    VT_BOOL impostata su VARIANT_TRUE. Indica che il chiamante è quello che ha scritto il valore nell'oggetto contesto e che non è stato propagato da un'altra operazione dipendente.
  3. Passare l'oggetto contesto IWbemContext in qualsiasi chiamata a IWbemServices::GetObject, IWbemServices::GetObjectAsync, IWbemServices::CreateInstanceEnum o IWbemServices::CreateInstanceEnumAsync tramite il parametro pCtx .

    Il passaggio dell'oggetto IWbemContext indica al provider di consentire il recupero di istanze parziali. In un recupero a istanza completa si imposta pCtx su un valore Null . Se il provider non supporta il recupero di istanze parziali, verrà visualizzato un messaggio di errore.

Se il provider non è conforme all'operazione di istanza parziale, il provider procede come se non si immettesse l'oggetto contesto oppure restituisce WBEM_E_UNSUPPORTED_PARAMETER.

Nell'esempio seguente viene descritto come eseguire un recupero completo dell'istanza di Win32_LogicalDisk e quindi viene eseguito un recupero parziale dell'istanza parziale della proprietà Win32_LogicalDisk.Caption .

#include <stdio.h>
#define _WIN32_DCOM
#include <wbemidl.h>
#pragma comment(lib, "wbemuuid.lib")
#include <iostream>
using namespace std;
#include <comdef.h>


void main(void)
{
    HRESULT hr;
    _bstr_t bstrNamespace;
    IWbemLocator *pWbemLocator = NULL;
    IWbemServices *pServices = NULL;
    IWbemClassObject *pDrive = NULL;
    

    hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);

    hr = CoInitializeSecurity(NULL, -1, NULL, NULL,
                         RPC_C_AUTHN_LEVEL_CONNECT,
                         RPC_C_IMP_LEVEL_IMPERSONATE,
                         NULL, EOAC_NONE, 0);
 
    if (FAILED(hr))
    {
       CoUninitialize();
       cout << "Failed to initialize security. Error code = 0x" 
            << hex << hr << endl;
       return;
    }

    hr = CoCreateInstance(CLSID_WbemLocator, NULL, 
                          CLSCTX_INPROC_SERVER, IID_IWbemLocator, 
                          (void**) &pWbemLocator);
    if( FAILED(hr) ) 
    {
        CoUninitialize();
        printf("failed CoCreateInstance\n");
        return;
    }
    
    bstrNamespace = L"root\\cimv2";
    hr = pWbemLocator->ConnectServer(bstrNamespace, 
              NULL, NULL, NULL, 0, NULL, NULL, &pServices);
    if( FAILED(hr) ) 
    {
        pWbemLocator->Release();
        CoUninitialize();
        printf("failed ConnectServer\n");
        return;
    }
    pWbemLocator->Release();
    printf("Successfully connected to namespace.\n");

    
    BSTR bstrPath = 
         SysAllocString(L"Win32_LogicalDisk.DeviceID=\"C:\"");
   // *******************************************************//
   // Perform a full-instance retrieval. 
   // *******************************************************//
    hr = pServices->GetObject(bstrPath,
                              0,0, &pDrive, 0);
    if( FAILED(hr) )
    { 
        pServices->Release();
        CoUninitialize();
        printf("failed GetObject\n");
        return;
    }    
    // Display the object
    BSTR  bstrDriveObj;
    hr = pDrive->GetObjectText(0, &bstrDriveObj);
    printf("%S\n\n", bstrDriveObj);

    pDrive->Release();
    pDrive = NULL;

   // *****************************************************//
   // Perform a partial-instance retrieval. 
   // *****************************************************//
    
    IWbemContext  *pctxDrive; // Create context object
    hr = CoCreateInstance(CLSID_WbemContext, NULL, 
                          CLSCTX_INPROC_SERVER, IID_IWbemContext, 
                          (void**) &pctxDrive);
    if (FAILED(hr))
    {
        pServices->Release();
        pDrive->Release();    
        CoUninitialize();
        printf("create instance failed for context object.\n");
        return;
    }
    
    VARIANT  vExtensions;
    VARIANT  vClient;
    VARIANT  vPropertyList;
    VARIANT  vProperty;
    SAFEARRAY  *psaProperties;
    SAFEARRAYBOUND saBounds;
    LONG  lArrayIndex = 0;
    
    // Add named values to the context object. 
    VariantInit(&vExtensions);
    V_VT(&vExtensions) = VT_BOOL;
    V_BOOL(&vExtensions) = VARIANT_TRUE;
    hr = pctxDrive->SetValue(_bstr_t(L"__GET_EXTENSIONS"), 
        0, &vExtensions);
    VariantClear(&vExtensions);

    VariantInit(&vClient);
    V_VT(&vClient) = VT_BOOL;
    V_BOOL(&vClient) = VARIANT_TRUE;
    hr = pctxDrive->SetValue(_bstr_t(L"__GET_EXT_CLIENT_REQUEST"), 
       0, &vClient);
    VariantClear(&vClient);
    // Create an array of properties to return.
    saBounds.cElements = 1;
    saBounds.lLbound = 0;
    psaProperties = SafeArrayCreate(VT_BSTR, 1, &saBounds);

    // Add the Caption property to the array.
    VariantInit(&vProperty);
    V_VT(&vProperty) = VT_BSTR;
    V_BSTR(&vProperty) = _bstr_t(L"Caption");
    SafeArrayPutElement(psaProperties, &lArrayIndex, 
       V_BSTR(&vProperty));
    VariantClear(&vProperty);
    
    VariantInit(&vPropertyList);
    V_VT(&vPropertyList) = VT_ARRAY | VT_BSTR;
    V_ARRAY(&vPropertyList) = psaProperties;
    // Put the array in the named value __GET_EXT_PROPERTIES.
    hr = pctxDrive->SetValue(_bstr_t(L"__GET_EXT_PROPERTIES"), 
        0, &vPropertyList);
    VariantClear(&vPropertyList);
    SafeArrayDestroy(psaProperties);

    // Pass the context object as the pCtx parameter of GetObject.
    hr = pServices->GetObject(bstrPath, 0, pctxDrive, &pDrive, 0);
    if( FAILED(hr) )
    { 
        pServices->Release();
        CoUninitialize();
        printf("failed property GetObject\n");
        return;
    }    
    // Display the object
    hr = pDrive->GetObjectText(0, &bstrDriveObj);
    printf("%S\n\n", bstrDriveObj);

    SysFreeString(bstrPath);

    VARIANT vFileSystem;
    // Attempt to get a property that was not requested.
    // The following should return a NULL property if
    // the partial-instance retrieval succeeded.

    hr = pDrive->Get(_bstr_t(L"FileSystem"), 0,
                       &vFileSystem, NULL, NULL);

    if( FAILED(hr) )
    { 
        pServices->Release();
        pDrive->Release();    
        CoUninitialize();
        printf("failed get for file system\n");
        return;
    }    
 
    if (V_VT(&vFileSystem) == VT_NULL)
        printf("file system variable is null - expected\n");
    else
        printf("FileSystem = %S\n", V_BSTR(&vFileSystem));
    
    VariantClear(&vFileSystem);

    pDrive->Release();    
    pctxDrive->Release();
    pServices->Release();
    pServices = NULL;    // MUST be set to NULL
    CoUninitialize();
    return;  // -- program successfully completed
};

Quando viene eseguito, l'esempio di codice precedente scrive le informazioni seguenti. La prima descrizione dell'oggetto proviene dal recupero dell'istanza completa. La seconda descrizione dell'oggetto è dal recupero parziale dell'istanza. L'ultima sezione mostra che viene visualizzato un valore Null se si richiede una proprietà non richiesta nella chiamata GetObject originale.

Successfully connected to namespace

instance of Win32_LogicalDisk
{
        Caption = "C:";
        Compressed = FALSE;
        CreationClassName = "Win32_LogicalDisk";
        Description = "Local Fixed Disk";
        DeviceID = "C:";
        DriveType = 3;
        FileSystem = "NTFS";
        FreeSpace = "3085668352";
        MaximumComponentLength = 255;
        MediaType = 12;
        Name = "C:";
        Size = "4581445632";
        SupportsFileBasedCompression = TRUE;
        SystemCreationClassName = "Win32_ComputerSystem";
        SystemName = "TITUS";
        VolumeName = "titus-c";
        VolumeSerialNumber = "7CB4B90E";
};

instance of Win32_LogicalDisk
{
        Caption = "C:";
        CreationClassName = "Win32_LogicalDisk";
        Description = "Local Fixed Disk";
        DeviceID = "C:";
        DriveType = 3;
        MediaType = 12;
        Name = "C:";
        SystemCreationClassName = "Win32_ComputerSystem";
        SystemName = "MySystem";
};

L'output seguente viene generato dall'esempio precedente.

file system variable is null - expected
Press any key to continue