Using the CIM Cmdlets in Windows PowerShell to solve a challenge

Introduced in PowerShell 3.0 and further enhanced in PowerShell 4.0, the CIM (Common Information Model) Cmdlets makes it easier to work with WMI (Windows Management Instrumentation). You can find an introduction to the new CIM Cmdlets in this article on the Windows PowerShell Teams blog.

In this article we will look at a usage scenario for the new CIM Cmdlets.

The Challenge

When adding a disk to a Windows Failover Cluster, the clustered disk is added to the cluster as a resource. The resource is automatically named “Cluster Disk N”, where N is the first available number. The challenge we are going to solve is renaming the newly added cluster disk based on the name (File System Label) of the underlying disk volume. This is typically an NTFS volume which is initialized and formatted before the disk is added to the cluster:


Using the Failover Cluster Manager in Windows Server we can view the name of the underlying volume:


Based on this observation we can manually rename the cluster resource. However, in a large cluster with many disks this task is a good candidate for automation.

Solving the challenge using CIM Cmdlets

By using the Get-ClusterResource cmdlet in the FailoverClusters PowerShell module we can view information about the disk, but there isnt an easy way to view the name of the underlying volume.

Due to that, we can rather leverage the Get-CimInstance cmdlet to list all cluster resources in the MSCluster_Resource class:


We use the –Filter parameter to specify that we only want cluster resources of the type “Physical Disk”, if not we would also get cluster resources such as cluster IP addresses, cluster names and so on.

Based on the information available on the object produced by Get-CimInstance, we can see many cluster related properties. However, no information about the underlying volume is available.

There is one cmdlet in the CIMCmdlets module which can get all the associated instances for a particular instance – the Get-CimAssociatedInstance cmdlet. In this scenario, we want to find all related volumes for the cluster disks. We start by finding all related instances:


This produced a large list of different kind of objects. We can use Get-Member to view information about the objects, and Select-Object to view the unique object types:


Based on the above output, the MSCluster_DiskPartition looks like a good candidate. We can use the –ResultClass parameter of Get-CimAssociatedInstance in order to narrow down the results to the class we want:


This is excactly what we want, as we can see the VolumeLabel property on the above output.

Now that we have the information we want – the VolumeLabel property – we need to find a way to rename the cluster resource (“Cluster Disk 1”). We can start by looking for a Rename method on the MSCluster_DiskPartition object. Normally, we would use Get-Member to view the available methods:


Since the CIM cmdlets is using the Ws-Man (WS-Management) protocol, the objects we get returned is serialized/deserialized. Thus the objects methods is remove since we arent working with a “live” object. The Get-CimClass cmdlet can be used to get the class schema of a CIM class, which includes the methods.
Instead let`s try the Get-CimClass cmdlet to view the methods available on the mscluster_resource class:


As we can see, there is a Rename method which takes one parameter: newName.

In order to invoke the method, we can use the Invoke-CimMethod cmdlet where we specify Rename as the MethodName and provide the value we want to configure as a hash table on the Arguments parameter:


We provided the VolumeLabel property returned by the Get-CimAssociatedInstance cmdlet as the value for the newName parameter, effectively solving the challenge.

After invoking the method, we can see the name of the cluster disk is immediately updated in Failover Cluster Manager:


When working with multiple cluster disks, we can use a foreach loop in order to invoke the rename method for all disks  if the name of the cluster resource does not match the name of the underlying disk volume: