Condividi tramite


Recupero di parte di un'istanza WMI

Un recupero parziale dell'istanza è quando WMI recupera solo un subset delle proprietà di un'istanza. Ad esempio, WMI potrebbe recuperare solo le proprietà Nome e Chiave . L'uso più comune del recupero parziale delle istanze si verifica su grandi enumerazioni che hanno più proprietà.

Recupero di parte di un'istanza WMI tramite 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 parte di un'istanza WMI tramite C# (System.Management)

È possibile recuperare una singola proprietà di un'istanza creando un nuovo 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 in genere più lente e non si adattano altrettanto bene rispetto alle rispettive 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 parte di un'istanza WMI tramite 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 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 parziale dell'istanza con C++

  1. Creare un oggettoIWbemContextcon una chiamata a CoCreateInstance.

    Un oggetto contesto è un oggetto utilizzato da WMI 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 un'istanza parziale.

  2. Aggiungere __GET_EXTENSIONS, __GET_EXT_CLIENT_REQUEST e tutti gli altri valori denominati che descrivono le proprietà da recuperare nell'oggettoIWbemContext.

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

    Valore denominato Descrizione
    __OTTENERE_ESTENSIONI
    VT_BOOL impostato su VARIANTE_VERO. Usato per segnalare che vengono usate operazioni di recupero di istanze parziali. In questo modo è possibile eseguire un controllo singolo rapido senza dover enumerare l'intero oggetto contesto. Se si utilizza uno degli altri valori, questo deve essere.
    __GET_EXT_PROPERTIES
    SAFEARRAY di stringhe che elencano le proprietà da recuperare. Non può essere specificato contemporaneamente con __GET_EXT_KEYS_ONLY.
    Un asterisco "*" è un nome di proprietà non valido per __GET_EXT_PROPERTIES.
    __GET_EXT_KEYS_ONLY
    VT_BOOL impostato su VARIANT_TRUE. Indica che nell'oggetto restituito devono essere specificate solo le chiavi. Non è possibile specificare contemporaneamente con __GET_EXT_PROPERTIES. Ha invece la precedenza sui __GET_EXT_PROPERTIES.
    __GET_EXT_CLIENT_REQUEST
    VT_BOOL impostato 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. Passa l'oggetto contesto IWbemContext in qualsiasi chiamata a IWbemServices::GetObject, IWbemServices::GetObjectAsync, IWbemServices::CreateInstanceEnumo IWbemServices::CreateInstanceEnumAsync tramite il parametro pCtx.

    Il passaggio dell'oggetto IWbemContext istruisce il provider a consentire recuperi parziali di istanze. In un recupero di istanza completa, è necessario impostare pCtx su un valore null. Se il provider non supporta il recupero parziale dell'istanza, verrà visualizzato un messaggio di errore.

Se il provider non può conformarsi all'operazione di istanza parziale, il provider procede come se l'oggetto di contesto non fosse stato inserito oppure restituisce WBEM_E_UNSUPPORTED_PARAMETER.

Nell'esempio seguente viene descritto come eseguire un recupero completo dell'istanza di Win32_LogicalDisk, quindi viene eseguito un recupero parziale dell'istanza 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 proviene dal recupero parziale dell'istanza. L'ultima sezione mostra che viene visualizzato un valore null se si richiede una proprietà non richiesta nella chiamata originaleGetObject.

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