Получение части экземпляра WMI

Частичное извлечение экземпляра — это когда WMI извлекает только подмножество свойств экземпляра. Например, WMI может получить только свойства Name и Key . Извлечение частичного экземпляра чаще всего используется для больших перечислений с несколькими свойствами.

Получение части экземпляра WMI с помощью PowerShell

Вы можете получить отдельное свойство экземпляра с помощью командлета Get-WmiObject; само свойство можно извлечь и отобразить несколькими способами. Как и при извлечении экземпляра, PowerShell по умолчанию возвращает все экземпляры заданного класса; Необходимо указать определенное значение, если вы хотите получить только один экземпляр.

В следующем примере кода отображается серийный номер тома для экземпляра класса 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

Получение части экземпляра WMI с помощью C# (System.Management)

Вы можете получить отдельное свойство экземпляра, создав новый объект ManagementObject , используя сведения о конкретном экземпляре. Затем можно неявно получить одно или несколько свойств экземпляра с помощью метода GetPropertyValue .

Примечание

System.Management — это исходное пространство имен .NET, используемое для доступа к WMI; Однако API-интерфейсы в этом пространстве имен обычно работают медленнее и не масштабируются по сравнению с более современными аналогами Microsoft.Management.Infrastructure .

В следующем примере кода отображается серийный номер тома для экземпляра класса Win32_LogicalDisk .

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

Получение части экземпляра WMI с помощью VBScript

Вы можете получить отдельное свойство экземпляра с помощью GetObject.

В следующем примере кода отображается серийный номер тома для экземпляра класса Win32_LogicalDisk .

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

Получение части экземпляра WMI с помощью C++

Следующая процедура используется для запроса получения частичного экземпляра с помощью C++.

Запрос частичного получения экземпляра с помощью C++

  1. Создайте объект IWbemContext с помощью вызова CoCreateInstance.

    Объект контекста — это объект, который WMI использует для передачи дополнительных сведений поставщику WMI. В этом случае вы используете объект IWbemContext , чтобы указать поставщику обработать получение частичного экземпляра.

  2. Добавьте __GET_EXTENSIONS, __GET_EXT_CLIENT_REQUEST и любые другие именованные значения, описывающие свойства, которые требуется извлечь, в объект IWbemContext .

    В следующей таблице перечислены различные именованные значения, используемые в вызове извлечения.

    Именованное значение Описание
    __GET_EXTENSIONS
    VT_BOOL задано значение VARIANT_TRUE. Используется для обозначения того, что используются операции извлечения частичного экземпляра. Это позволяет быстро и проверка без перечисления всего объекта контекста. Если используется какое-либо из других значений, оно должно иметь значение .
    __GET_EXT_PROPERTIES
    SAFEARRAY строк со списком извлекаемых свойств. Нельзя указать одновременно с __GET_EXT_KEYS_ONLY.
    Звездочка "*" является недопустимым именем свойства для __GET_EXT_PROPERTIES.
    __GET_EXT_KEYS_ONLY
    VT_BOOL задано значение VARIANT_TRUE. Указывает, что в возвращаемом объекте должны быть указаны только ключи. Невозможно указать одновременно с __GET_EXT_PROPERTIES. Вместо этого имеет приоритет над __GET_EXT_PROPERTIES.
    __GET_EXT_CLIENT_REQUEST
    VT_BOOL задано значение VARIANT_TRUE. Указывает, что вызывающий объект записал значение в объект контекста и что оно не было распространено из другой зависимой операции.
  3. Передайте объект контекста IWbemContext во все вызовы IWbemServices::GetObject, IWbemServices::GetObjectAsync, IWbemServices::CreateInstanceEnum или IWbemServices::CreateInstanceEnumAsync с помощью параметра pCtx .

    Передача объекта IWbemContext указывает поставщику разрешить извлечение частичного экземпляра. При извлечении полного экземпляра pCtx следует задать значение NULL . Если поставщик не поддерживает частичное извлечение экземпляров, вы получите сообщение об ошибке.

Если поставщик не может соответствовать операции частичного экземпляра, поставщик либо продолжает работу так, как если бы вы не ввели объект контекста, или возвращает WBEM_E_UNSUPPORTED_PARAMETER.

В следующем примере описывается выполнение полного извлечения экземпляра Win32_LogicalDisk, а затем частичного извлечения экземпляра свойства 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
};

При выполнении в предыдущем примере кода записываются следующие сведения. Первое описание объекта — это получение полного экземпляра. Второе описание объекта — из получения частичного экземпляра. В последнем разделе показано, что при запросе свойства, которое не было запрошено в исходном вызове GetObject, вы получаете значение NULL.

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

Приведенные ниже выходные данные создаются в предыдущем примере.

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