更新實例的一部分

有時候,您可能只想要更新實例的一部分。 例如,某些實例有大量的屬性。 如果您必須更新大量這些實例,可能會降低系統效能。 因此,您可以選擇只更新實例的一部分,因而減少您必須在 WMI 中傳送和擷取的資訊量。 不過,WMI 並不直接支援部分實例作業,也不支援大部分的提供者。 因此,如果您撰寫使用部分實例作業的應用程式,請準備好讓呼叫失敗,並出現 C ++ 中的 WBEM_E_PROVIDER_NOT_CAPABLE或WBEM_E_NOT_SUPPORTED 錯誤碼。 在指令碼語言中,錯誤碼為 wbemErrProviderNotCapablewbemErrNotSupported

在腳本中,只有在企業中更新一或兩個可寫入屬性時,才需要這項作業來協助效能。 否則,一般 VBScript 會呼叫 SWbemObject.Put_SWbemObject.PutAsync_,雖然似乎要寫入整個物件,但實際上只會更新提供者已啟用寫入的屬性。

下列程式說明如何使用 PowerShell 要求部分實例更新。

使用 PowerShell 要求部分實例更新

  1. 擷取您想要更新的物件路徑。

    您可以手動描述路徑,或查詢物件,然後擷取 __Path 屬性。

    $myWMIDrivePath = (get-wmiObject Win32_LogicalDisk -filter "Name = 'C:'").__Path
    #or
    $myWmiDrivePath = \\myComputer\root\cimv2:Win32_LogicalDisk.DeviceID="C:"
    
  2. 設定雜湊表,列出要更新的屬性名稱,並在 呼叫 Set-WmiInstance時使用此雜湊表。

    $newDriveName = @{VolumeName = "OSDisk"}
    Set-WmiInstance -Path $myWMIDrivePath -Arguments $newDriveName
    

下列程式描述如何使用 C# 要求部分實例更新。

注意

System.Management 是用來存取 WMI 的原始 .NET 命名空間;不過,此命名空間中的 API 通常較慢,而且不會相對於其較新式 的 Microsoft.Management.Infrastructure 對應專案進行調整。

 

使用 C 要求部分實例更新#

  1. 建立新的 ManagementObject 物件,代表要更新的特定實例。

    using System.Management;
    ...
    ManagementObject myDisk = new ManagementObject("Win32_LogicalDisk.DeviceID='C:'");
    
  2. 使用 對 ManagementObject.SetPropertyValue的呼叫來設定屬性值。

    myDisk.SetPropertyValue("VolumeName", "OSDisk");
    

下列程式描述如何使用 VBScript 要求部分實例更新。

使用 VBScript 要求部分實例更新

  1. 建立 SWbemNamedValueSet 內容物件。

    Set objwbemNamedValueSet = CreateObject ("WbemScripting.SWbemNamedValueSet")
    
  2. 使用 SWbemNamedValueSet.Add 方法,將 Put 擴充值 「__PUT_EXTENSIONS」 和 「__PUT_EXT_CLIENT_REQUEST」 新增至內容物件。

    objwbemNamedValueSet.Add "__PUT_EXTENSIONS", True
    objwbemNamedValueSet.Add "__PUT_EXT_CLIENT_REQUEST", True
    
  3. 設定陣列,其中列出要更新的屬性名稱,並將此陣列新增至 SWbemNamedValueSet 內容物件,並加上 Put 擴充值 「__PUT_EXT_PROPERTIES」。

    arProperties = Array("propertyname1", "propertyname2") 
    objwbemNamedValueSet.Add "__PUT_EXT_PROPERTIES", arProperties
    
  4. SWbemObject.Put_呼叫wbemChangeFlagUpdateOnlyiFlags參數設定為 。 如果沒有這個旗標,呼叫將會失敗,且內容無效。

  5. SWbemObject.Put_SWbemObject.PutAsync_objwbemNamedValueSet參數中,將您的旗標和內容物件傳遞至提供者。

    call objSystem.put_( wbemChangeFlagUpdateOnly, objwbemNamedValueSet)
    

下列程式描述如何使用 C++ 要求部分實例更新。

使用 C++ 要求部分實例更新

  1. 使用CoCreateInstance的呼叫建立IWbemCoNtext物件。

    內容物件是 WMI 用來將詳細資訊傳遞至 WMI 提供者的物件。 在此情況下,您會使用 IWbemCoNtext 物件來指示提供者接受部分實例更新。

  2. 使用IWbemCoNtext::SetValue呼叫,將 「__PUT_EXTENSIONS」 和 「__PUT_EXT_CLIENT_REQUEST」 具名值新增至IWbemCoNtext物件。

    下表列出 「__PUT_EXTENSIONS」 和 「__PUT_EXT_CLIENT_REQUEST」 的意義。

    具名值 描述
    「__PUT_EXTENSIONS」 VT_BOOL 設定為 VARIANT_TRUE。 值,表示已指定一或多個其他內容值。 這可讓快速檢查提供者內的內容物件,以判斷是否使用部分實例更新。
    「__PUT_EXT_CLIENT_REQUEST」 VT_BOOL 設定為 VARIANT_TRUE。 在初始要求期間由用戶端設定。 這個值是用來防止重新進入錯誤。

     

  3. 視需要將__PUT_EXT_STRICT_NullS、__PUT_EXT_PROPERTIES或__PUT_EXT_ATOMIC新增至 IWbemCoNtext 物件,以及另一個 IWbemCoNtext::SetValue呼叫。

    下表列出具名值的意義。

    具名值 描述
    「__PUT_EXT_STRICT_NullS」 VT_BOOL 設定為 VARIANT_TRUE。 表示用戶端已刻意將屬性設定為 VT_Null ,並預期寫入作業成功。 如果提供者無法將值設定為 Null,則應該報告錯誤。
    「__PUT_EXT_PROPERTIES」 包含要更新之屬性名稱清單的字串SAFEARRAY。 可以單獨使用,或與 「__PUT_EXT_PROPERTIES」 搭配使用。 這些值位於正在寫入的 實例中。
    「__PUT_EXT_ATOMIC」 VT_BOOL 設定為 VARIANT_TRUE。 表示所有更新都必須同時成功 (不可部分完成的語意) ,否則提供者必須還原。 沒有部分成功。 可以單獨使用或與其他旗標搭配使用。

     

  4. iFlags 參數設定為 WBEM_FLAG_UPDATE_ONLY。 如果沒有這個旗標,呼叫將會失敗,且內容無效。

  5. IWbemCoNtext內容物件傳遞至pCtx參數中的任何呼叫IWbemServices::P utInstanceIWbemServices::P utInstanceAsync

    傳遞 IWbemCoNtext 物件會指示提供者允許部分實例更新。 在完整實例更新中,您會將 pCtx 設定為 Null

    如果呼叫中存在的內容物件不包含 「__PUT_EXTENSIONS」,提供者可能會寫入任何必要的屬性。 如果內容物件中有 「__PUT_EXTENSIONS」,WMI 會要求提供者完全遵循作業的語意,否則會失敗呼叫。 如需詳細資訊,請參閱 處理提供者中的拒絕存取訊息