Hi Cluster Fans,

In the forums we have noticed several people have question about how to manipulate a Cluster Object’s private properties using WMI.  To work with private properties it’s important to understand how private properties work.  Private properties of any cluster object are dynamic in nature, so these properties cannot be predefined in WMI .mof files with the class definition and these properties could differ between instances of the same class.  So the Cluster WMI provider defines a property of name “PrivateProperties”.  The value of this property is an embedded object which is created at runtime dynamically, after looking into the cluster object and reading its private properties.  This embedded object is a WMI Class with just the properties and its values.

 

To get or set values from private properties, first we get the value of the property “PrivateProperty” of the object.  The value is a VT_UNKNOWN, so next it need to be converted in IWbemClassObject object (C++\COM) or ManagementBaseObject (C#).  Finally using this object you need to call Get\Put with the desired property name.

 

If you are making changes to the private property, you need to do save the PrivateProperties object and the parent object.

 

Here is a sample code in C#:

 

    public virtual object GetProperty(string propertyName, bool isPrivateProperty)

    {

      if (null == propertyName)

        throw new System.ArgumentNullException("propertyName", "GetProperty(): propertyName input parameter value is null.");

      System.Object propertyVal = null;

      ManagementObject mgmtObj = null;

      ManagementBaseObject privPropsMgmtObj = null;

      try

      {

        // Get the WMI Object

        mgmtObj = WmiHelperMethods.GetManagementObject(this.WmiConnectionScope, this.WmiPath);

        if (false == isPrivateProperty)

          propertyVal = mgmtObj.Properties[propertyName].Value;

        else

        {

          privPropsMgmtObj = (ManagementBaseObject)mgmtObj.Properties["PrivateProperties"].Value;

          propertyVal = privPropsMgmtObj[propertyName];         

        }

      }

      return propertyVal;

    }

 

    public virtual void SetProperty(string propertyName, object propertyValue, bool isPrivateProperty)

    {

      if (null == propertyName)

        throw new System.ArgumentNullException("propertyName", "SetProperty(): propertyName input parameter value is null.");

      ManagementObject mgmtObj = null;

      ManagementBaseObject privPropsMgmtObj = null;

      try

      {

        mgmtObj = WmiHelperMethods.GetManagementObject(this.WmiConnectionScope, this.WmiPath);

        if (false == isPrivateProperty)

        {

          mgmtObj.Properties[propertyName].Value = propertyValue;

          mgmtObj.Put();

        }

        else

        {

          privPropsMgmtObj = (ManagementBaseObject)mgmtObj.Properties["PrivateProperties"].Value;

          privPropsMgmtObj.Properties[propertyName].Value = propertyValue;

          mgmtObj.Properties["PrivateProperties"].Value = privPropsMgmtObj;

          mgmtObj.Put();

        }

      }

    }

 

 

Here is a sample code in C++ using COM:

 

   CComPtr<IWbemClassObject> piClusterObject;

 

// piWbemService is an instance of IWbemServices

    hr = piWbemService->GetObjectW (CComBSTR (L"<Cluster Object Path>"),

       0, NULL, &piClusterObject, NULL);

 

    // Validation code here….

 

    CComVariant varValue;

    CIMTYPE cimType(CIM_ILLEGAL);

    hr = piClusterObject->Get (CComBSTR (L"PrivateProperties"),

       0, &varValue,&cimType,0);

 

    if (SUCCEEDED(hr) && cimType != CIM_ILLEGAL)

    {

IWbemClassObject *privateProperty = (IWbemClassObject *) varValue.ppunkVal;

 

// now if you call Get\Put on privateProperty you should be able to get the private property

// eg.

CComVariant propValue;

privateProperty->Get (CComBSTR (L"<a property name>"),0,&propValue,NULL);

 

// Similarly to update a private property you can call Put

hr = privateProperty->Put (CComBSTR (L"<Property Name>"),0,& propValue,NULL);

 

// once you have updated the private property you need to update the parent object with the updated private property

CComVariant updatedValue(privateProperty);

       hr = piClusterObject->Put (CComBSTR (L"PrivateProperties"),0,& updatedValue,NULL);

 

       // Update the WMI Provider\Server with the changes

       // The below call would trigger changes on the cluster or update the cluster with updated values.

       // if there is any error during the upgrade you would get it now.

       hr = piWbemService->PutInstance( piClusterObject,

                   WBEM_FLAG_UPDATE_ONLY,

                   NULL,

                   NULL );

}

 

Changing the parameters (private properties) of IP address resource is not trivial, especially in cases where you would like to change the IP address (static) or change the network or subnet mask.

All these three parameters are linked to each other and every time you have to change one you need to modify all 3 at the same time. If you do not do , the update would not happen and you may see errors.

 

Thanks,

Vikas Kumar
Software Development Engineer in Test II

Clustering & High-Availability

Microsoft