Abrufen eines Teils einer WMI-Instanz

Ein partieller erfolgt, wenn WMI nur eine Teilmenge der Eigenschaften einer Instanz abruft. Beispielsweise konnte WMI nur die Eigenschaften Name und Key abrufen. Teilweise Instanzabrufe werden in der Regel bei großen Enumerationen mit mehreren Eigenschaften ausgeführt.

Abrufen eines Teils einer WMI-Instanz mithilfe von PowerShell

Sie können eine einzelne Eigenschaft einer Instanz mithilfe von Get-WmiObject abrufen. Die Eigenschaft selbst kann auf verschiedene Arten abgerufen und angezeigt werden. Wie beim Abrufen einer Instanz gibt PowerShell standardmäßig alle Instanzen einer bestimmten Klasse zurück. Sie müssen einen bestimmten Wert angeben, wenn Sie nur eine einzelne Instanz abrufen möchten.

Im folgenden Codebeispiel wird die Volumeseriennummer für eine Instanz der Klasse Win32_LogicalDisk angezeigt.

(Get-WmiObject -class Win32_logicalDisk).DeviceID

#or

Get-WmiObject -class Win32_LogicalDisk | format-list DeviceID

#or

$myDisk = Get-WmiObject -class Win32_LogicalDisk
$myDisk.DeviceID

Abrufen eines Teils eines WMI-Instanz mithilfe von C# (System.Management)

Sie können eine einzelne Eigenschaft einer Instanz abrufen, indem Sie mithilfe der Daten einer bestimmten Instanz ein neues ManagementObject erstellen. Anschließend können Sie implizit eine oder mehrere Eigenschaften der Instanz mit der GetPropertyValue-Methode abrufen.

Hinweis

System.Management war der ursprüngliche .NET-Namespace, der für den Zugriff auf WMI verwendet wurde. Die APIs in diesem Namespace sind jedoch im Allgemeinen langsamer und skalieren im Vergleich zu ihren moderneren Microsoft.Management.Infrastructure-Entsprechungen nicht so gut.

Im folgenden Codebeispiel wird die Volumeseriennummer für eine Instanz der Klasse Win32_LogicalDisk angezeigt.

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

Abrufen eines Teils einer WMI-Instanz mithilfe von VBScript

Sie können eine einzelne Eigenschaft einer Instanz mithilfe von GetObject abrufen.

Im folgenden Codebeispiel wird die Volumeseriennummer für eine Instanz der Klasse Win32_LogicalDisk angezeigt.

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

Abrufen eines Teils einer WMI-Instanz mithilfe von C++

Das folgende Verfahren wird verwendet, um einen partiellen Instanzabruf mithilfe von C++ anzufordern.

So fordern Sie einen partiellen Instanzabruf mit C++ an

  1. Erstellen Sie ein IWbemContext-Objekt mit einem Aufruf von CoCreateInstance.

    Ein Kontextobjekt ist ein Objekt, das von WMI verwendet wird, um weitere Informationen an einen WMI-Anbieter zu übergeben. In diesem Fall verwenden Sie das IWbemContext-Objekt, um den Anbieter anzuweisen, einen partiellen Instanzabruf zu verarbeiten.

  2. Fügen Sie dem IWbemContext-Objekt __GET_EXTENSIONS, __GET_EXT_CLIENT_REQUEST und alle anderen benannten Werte hinzu, die die Eigenschaften beschreiben, die Sie abrufen möchten.

    In der folgenden Tabelle sind die verschiedenen benannten Werte aufgeführt, die in Ihrem Abrufaufruf verwendet werden.

    Benannter Wert BESCHREIBUNG
    __GET_EXTENSIONS
    VT_BOOL auf VARIANT_TRUE festgelegt. Wird verwendet, um zu signalisieren, dass partielle Instanzabrufvorgänge verwendet werden. Dies ermöglicht eine schnelle, einzelne Überprüfung, ohne das gesamte Kontextobjekt auflisten zu müssen. Wenn einer der anderen Werte verwendet wird, ist dieser Wert erforderlich.
    __GET_EXT_PROPERTIES
    SAFEARRAY von Zeichenfolgen, die die abzurufenden Eigenschaften auflisten. Er kann nicht gleichzeitig mit __GET_EXT_KEYS_ONLY angegeben werden.
    Ein Sternchen „*“ ist ein ungültiger Eigenschaftsname für __GET_EXT_PROPERTIES.
    __GET_EXT_KEYS_ONLY
    VT_BOOL auf VARIANT_TRUE festgelegt. Gibt an, dass im zurückgegebenen Objekt nur Schlüssel bereitgestellt werden sollen. Er kann nicht gleichzeitig mit __GET_EXT_KEYS_ONLY angegeben werden. Stattdessen hat er Vorrang vor __GET_EXT_PROPERTIES.
    __GET_EXT_CLIENT_REQUEST
    VT_BOOL auf VARIANT_TRUE festgelegt. Gibt an, dass der Aufrufer derjenige war, der den Wert in das Kontextobjekt geschrieben hat, und dass er nicht von einem anderen abhängigen Vorgang weitergegeben wurde.
  3. Übergeben Sie das IWbemContext-Kontextobjekt über den pCtx-Parameter an alle Aufrufe von IWbemServices::GetObject, IWbemServices::GetObjectAsync, IWbemServices::CreateInstanceEnum oder IWbemServices::CreateInstanceEnumAsync.

    Durch Übergeben des IWbemContext-Objekts wird der Anbieter angewiesen, partielle Instanzabrufe zuzulassen. Bei einem vollständigen Instanzabruf würden Sie pCtx auf einen NULL-Wert festlegen. Wenn der Anbieter den teilweisen Instanzabruf nicht unterstützt, erhalten Sie eine Fehlermeldung.

Wenn der Anbieter den partiellen Instanzvorgang nicht einhalten kann, wird der Anbieter entweder so fortgesetzt, als ob Sie das Kontextobjekt nicht eingegeben haben, oder es wird WBEM_E_UNSUPPORTED_PARAMETER zurückgegeben.

Im folgenden Beispiel wird beschrieben, wie sie einen vollständigen Instanzabruf von Win32_LogicalDisk und anschließend einen teilweisen Instanzabruf der Eigenschaft Win32_LogicalDisk.Caption ausführen.

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

Bei Ausführung werden im vorherigen Codebeispiel die folgenden Informationen geschrieben. Die erste Objektbeschreibung stammt aus dem vollständigen Instanzabruf. Die zweite Objektbeschreibung stammt aus dem partiellen Instanzabruf. Der letzte Abschnitt zeigt, dass Sie einen NULL-Wert erhalten, wenn Sie eine Eigenschaft anfordern, die im ursprünglichen GetObject-Aufruf nicht angefordert wurde.

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

Die folgende Ausgabe wird im vorherigen Beispiel generiert.

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