Compartir a través de


Recuperación de parte de una instancia de WMI

Una recuperación de instancia parcial se produce cuando WMI recupera solo un subconjunto de las propiedades de una instancia. Por ejemplo, puede que WMI solo recupere las propiedades Name y Key. El uso más común de la recuperación de instancia parcial tiene lugar en enumeraciones grandes con varias propiedades.

Recuperación de parte de una instancia de WMI con PowerShell

Puede recuperar una propiedad individual de una instancia mediante Get-WmiObject; la propiedad en sí se puede recuperar y mostrar de varias maneras. Al igual que con la recuperación de una instancia, PowerShell devolverá de forma predeterminada todas las instancias de una clase dada. Si quiere recuperar una sola instancia, debe especificar un valor concreto.

En el ejemplo de código siguiente se muestra el número de serie del volumen para una instancia de la clase 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 una instancia de WMI mediante C# (System.Management)

Puede recuperar una propiedad individual de una instancia mediante la creación de un objeto ManagementObject con los detalles de una instancia específica. A continuación, puede recuperar implícitamente una o varias propiedades de la instancia con el método GetPropertyValue.

Nota

System.Management era el espacio de nombres de .NET original que se usaba para acceder a WMI; sin embargo, las API de este espacio de nombres suelen ser más lentas y no se escalan tan bien como sus homólogos más modernos Microsoft.Management.Infrastructure.

En el ejemplo de código siguiente se muestra el número de serie del volumen para una instancia de la clase Win32_LogicalDisk.

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

Recuperación de parte de una instancia de WMI mediante VBScript

Puede recuperar una propiedad individual de una instancia mediante GetObject.

En el ejemplo de código siguiente se muestra el número de serie del volumen para una instancia de la clase Win32_LogicalDisk.

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

Recuperar parte de una instancia de WMI mediante C++

El procedimiento siguiente se usa para solicitar una recuperación de instancia parcial mediante C++.

Para solicitar una recuperación de instancias parciales mediante C++

  1. Cree un objeto IWbemContext con una llamada a CoCreateInstance.

    Un objeto de contexto es un objeto que WMI usa para pasar más información a un proveedor de WMI. En este caso, está usando el objeto IWbemContext para indicar al proveedor que procese una recuperación de instancia parcial.

  2. Agregue __GET_EXTENSIONS, __GET_EXT_CLIENT_REQUEST y cualquier otro valor con nombre que describa las propiedades que quiere recuperar para el objeto IWbemContext.

    En la tabla siguiente se enumeran los distintos valores con nombre que se usan en la llamada de recuperación.

    Valor con nombre Descripción
    __GET_EXTENSIONS
    VT_BOOL establecido en VARIANT_TRUE. Se usa para indicar que se utilizan operaciones de recuperación de instancias parciales. Esto permite una comprobación rápida y única sin tener que enumerar todo el objeto de contexto. Si se usa alguno de los otros valores, debe ser este.
    __GET_EXT_PROPERTIES
    SAFEARRAY de cadenas que enumeran las propiedades que se van a recuperar. No se puede especificar simultáneamente con __GET_EXT_KEYS_ONLY.
    Un asterisco "*" es un nombre de propiedad no válido para __GET_EXT_PROPERTIES.
    __GET_EXT_KEYS_ONLY
    VT_BOOL establecido en VARIANT_TRUE. Indica que solo se deben proporcionar claves en el objeto devuelto. No se puede especificar simultáneamente con __GET_EXT_PROPERTIES. En su lugar, tiene prioridad sobre __GET_EXT_PROPERTIES.
    __GET_EXT_CLIENT_REQUEST
    VT_BOOL establecido en VARIANT_TRUE. Indica que el autor de llamada era el usuario que escribió el valor en el objeto de contexto y que no se propagó desde otra operación dependiente.
  3. Pase el objeto de contexto IWbemContext a cualquier llamada a IWbemServices::GetObject, IWbemServices::GetObjectAsync, IWbemServices::CreateInstanceEnum o IWbemServices::CreateInstanceEnumAsync mediante el parámetro pCtx.

    Al pasar el objeto IWbemContext, se indica al proveedor que permita las recuperaciones de instancias parciales. En una recuperación de instancia completa, se establecería pCtx en un valor null. Si el proveedor no admite la recuperación de instancias parciales, recibirá un mensaje de error.

Si el proveedor no puede cumplir con la operación de instancia parcial, este continúa como si no hubiera especificado el objeto de contexto, o bien devuelve WBEM_E_UNSUPPORTED_PARAMETER.

En el ejemplo siguiente se describe cómo realizar una recuperación de instancia completa de Win32_LogicalDisk y, después, se realiza una recuperación de instancia parcial de la propiedad 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
};

Cuando se ejecuta, el ejemplo de código anterior escribe la información siguiente. La primera descripción de objeto procede de la recuperación de instancia completa. La segunda descripción de objeto procede de la recuperación de instancia parcial. En la última sección se muestra que recibe un valor null si solicita una propiedad que no se solicitó en la llamada 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";
};

El ejemplo anterior genera la salida siguiente.

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