Извлечение части экземпляра 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++
Создайте объект IWbemContext с вызовом CoCreateInstance.
Объект контекста — это объект, который WMI использует для передачи дополнительных сведений поставщику WMI. В этом случае вы используете объект IWbemContext, чтобы указать поставщику на необходимость обработки запроса на извлечение частичного экземпляра.
Добавьте __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. Указывает, что вызывающий объект был тем, кто записал значение в объект контекста, и что оно не было передано из другой зависимой операции. Передайте объект контекста 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
};
При выполнении предыдущий пример кода записывает следующие сведения. Первое описание объекта получено из полного извлечения экземпляра. Второе описание объекта получено из извлечения частичного экземпляра. В последнем разделе показано, что вы получаете значение null, если запрашивается свойство, которое не было запрошено в исходном вызове GetObject.
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