Recuperar parte de uma instância WMI

Uma recuperação parcial de instância é quando o WMI recupera apenas um subconjunto das propriedades de uma instância. Por exemplo, o WMI poderia recuperar apenas as propriedades Name e Key. O uso mais comum da recuperação parcial de instância se dá em enumerações grandes que têm várias propriedades.

Recuperar parte de uma instância WMI usando o PowerShell

Você pode recuperar uma propriedade individual de uma instância usando Get-WmiObject. A própria propriedade pode ser recuperada e exibida de várias maneiras. Assim como na recuperação de uma instância, o PowerShell retornará por padrão todas as instâncias de uma determinada classe. Você deve determinar um valor específico se quiser recuperar apenas uma única instância.

O exemplo de código a seguir exibe o número de série do volume de uma instância da 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

Recuperar parte de uma instância WMI usando C# (System.Management)

Você pode recuperar uma propriedade individual de uma instância criando um novo ManagementObject usando os detalhes de uma instância específica. Em seguida, você pode recuperar implicitamente uma ou mais propriedades da instância com o método GetPropertyValue.

Observação

System.Management era o namespace original do .NET usado para acessar o WMI. No entanto, as APIs nesse namespace geralmente são mais lentas e não são dimensionadas tão bem em relação às contrapartes mais modernas do Microsoft.Management.Infrastructure.

O exemplo de código a seguir exibe o número de série do volume de uma instância da classe Win32_LogicalDisk.

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

Recuperar parte de uma instância WMI usando o VBScript

Você pode recuperar uma propriedade individual de uma instância usando GetObject.

O exemplo de código a seguir exibe o número de série do volume de uma instância da classe Win32_LogicalDisk.

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

Recuperar parte de uma instância WMI usando C++

O procedimento a seguir é usado para solicitar uma recuperação parcial de instância usando C++.

Para solicitar uma recuperação parcial de instância usando C++

  1. Crie um objeto IWbemContext com uma chamada para CoCreateInstance.

    Um objeto de contexto é um objeto usado pelo WMI para passar mais informações para um provedor WMI. Nesse caso, você está usando o objeto IWbemContext para instruir o provedor a processar uma recuperação parcial de instância.

  2. Adicione __GET_EXTENSIONS, __GET_EXT_CLIENT_REQUEST e quaisquer outros valores nomeados que descrevam as propriedades que você deseja recuperar para o objeto IWbemContext.

    A tabela a seguir lista os diferentes valores nomeados usados em sua chamada de recuperação.

    Valor nomeado Descrição
    __GET_EXTENSIONS
    VT_BOOL definido como VARIANT_TRUE. Usado para sinalizar que operações de recuperação parcial de instância estão sendo usadas. Isso permite uma verificação rápida e única sem a necessidade de enumerar todo o objeto de contexto. Se algum dos outros valores for usado, este também deve ser.
    __GET_EXT_PROPERTIES
    SAFEARRAY de cadeias de caracteres listando as propriedades a serem recuperadas. Não é possível especificar simultaneamente com __GET_EXT_KEYS_ONLY.
    Um asterisco "*" é um nome de propriedade inválido para __GET_EXT_PROPERTIES.
    __GET_EXT_KEYS_ONLY
    VT_BOOL definido como VARIANT_TRUE. Indica que somente as chaves devem ser fornecidas no objeto retornado. Não é possível especificar simultaneamente com __GET_EXT_PROPERTIES. Em vez disso, tem precedência sobre __GET_EXT_PROPERTIES.
    __GET_EXT_CLIENT_REQUEST
    VT_BOOL definido como VARIANT_TRUE. Indica que o chamador foi quem escreveu o valor no objeto de contexto e que ele não foi propagado a partir de outra operação dependente.
  3. Passe o objeto de contexto IWbemContext para qualquer chamada a IWbemServices::GetObject, IWbemServices::GetObjectAsync, IWbemServices::CreateInstanceEnum ou IWbemServices::CreateInstanceEnumAsync por meio do parâmetro pCtx.

    Passar o objeto IWbemContext instrui o provedor a permitir recuperações parciais de instância. Em uma recuperação completa de instância, você definiria pCtx como um valor nulo. Se o provedor não der suporte à recuperação parcial de instância, você receberá uma mensagem de erro.

Se o provedor não puder cumprir a operação parcial de instância, ele continuará como se você não tivesse inserido o objeto de contexto ou retornará WBEM_E_UNSUPPORTED_PARAMETER.

O exemplo a seguir descreve como executar uma recuperação completa de instância de Win32_LogicalDisk e, em seguida, executar uma recuperação parcial de instância da propriedade 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 executado, o exemplo de código anterior grava as informações a seguir. A primeira descrição do objeto é da recuperação completa da instância. A segunda descrição do objeto é da recuperação parcial da instância. A última seção mostra que você receberá um valor nulo se solicitar uma propriedade que não foi solicitada na chamada GetObject original.

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

A saída a seguir é gerada pelo exemplo anterior.

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