Hi Clustering PowerShell Scripters,

 

One of the things we’ve provided in Failover Clustering PowerShell is a set of CMDlets to easily create highly available workloads in a cluster.

 

PS C:\Windows\system32> Get-Command -Module FailoverClusters | ?{ $_.Name -like "Add-Cluster*Role" }

CommandType     Name                                                Definition

-----------     ----                                                ----------

CMDlet          Add-ClusterFileServerRole                           Add-ClusterFileServerRole [[-Name] <String>] [-S...

CMDlet          Add-ClusterGenericApplicationRole                   Add-ClusterGenericApplicationRole [[-Name] <Stri...

CMDlet          Add-ClusterGenericScriptRole                        Add-ClusterGenericScriptRole [[-Name] <String>] ...

CMDlet          Add-ClusterGenericServiceRole                       Add-ClusterGenericServiceRole [[-Name] <String>]...

CMDlet          Add-ClusterPrintServerRole                          Add-ClusterPrintServerRole [[-Name] <String>] [-...

CMDlet          Add-ClusterServerRole                               Add-ClusterServerRole [[-Name] <String>] [-Stora...

CMDlet          Add-ClusterVirtualMachineRole                       Add-ClusterVirtualMachineRole [[-Name] <String>]...

 

Each of the above CMDlets takes care of:

·         Creating the cluster group

·         Moving disk resource(s) into the group

·         Creating resources which may include creating the correct IP resources depending on your cluster network configuration (number of IPs and DHCP vs. static IPs)

·         Setting properties for each resource created

·         Setting dependencies between resources

·         Bringing the resources online

 

With that said, you’ll notice that we have not provided a CMDlet for each and every clustered workload we can create through our HA Wizard in our Failover Cluster Manager GUI.

 

 

 

In this blog, I will show you how easy it is to create other workloads using PowerShell without the extra steps above.  The secret lies in the Add-ClusterServerRole CMDlet.

To illustrate this, I’ll be using the Microsoft Distributed Transaction Coordinator, MSDTC, role as an example. That might be useful if you’re trying to automate your SQL Server installs. Note that while this is focused on MSDTC, you can use the same concepts for other workloads.

 

For comparison purposes, I created a DTC workload named ahmedbc4Dtc on my cluster using the Failover Cluster Manager GUI. As seen here, that populated the group with the right resources and the correct dependencies between the resources.

 

PS C:\Windows\system32> Get-ClusterGroup ahmedbc4Dtc

Name                                    OwnerNode

----                                    ---------

ahmedbc4Dtc                             ahmedbc4-n2

 

PS C:\Windows\system32> Get-ClusterGroup ahmedbc4Dtc | Get-ClusterResource | ft -auto

Name                                                State  Group       ResourceType

----                                                -----  -----       ------------

ahmedbc4Dtc                                         Online ahmedbc4Dtc Network Name

Cluster Disk 6                                      Online ahmedbc4Dtc Physical Disk

IP Address 157.55.88.0 (2)                          Online ahmedbc4Dtc IP Address

IP Address 2001:4898:0:fff:200:5efe:157.55.88.0 (2) Online ahmedbc4Dtc IPv6 Tunnel Address

IP Address 2001:4898:f0:1000:: (2)                  Online ahmedbc4Dtc IPv6 Address

MSDTC-ahmedbc4Dtc                                   Online ahmedbc4Dtc Distributed Transaction Coordinator

 

PS C:\Windows\system32> Get-ClusterGroup ahmedbc4Dtc | Get-ClusterResource | Get-ClusterResourceDependency | ft -auto

Resource                                            DependencyExpression

--------                                            --------------------

ahmedbc4Dtc                                         [IP Address 157.55.88.0 (2)] or [IP Address 2001:4898:f0:1000:: ...

Cluster Disk 6

IP Address 157.55.88.0 (2)

IP Address 2001:4898:0:fff:200:5efe:157.55.88.0 (2) ([IP Address 157.55.88.0 (2)])

IP Address 2001:4898:f0:1000:: (2)

MSDTC-ahmedbc4Dtc                                   ([ahmedbc4Dtc]) and ([Cluster Disk 6])

 

Now, how can I create something similar with PowerShell?

 

The easiest way is to create a base server role with the Add-ClusterServerRole CMDlet. I named it ahmedbc4Dtc1. This CMDlet does the heavy weight lifting for you, including creating the right number of IP resources and whether they are DHCP or statically configured based on your cluster networking configuration.  It also moves the disk resource for you in the group and sets the right dependencies between the network name resource and the IP resources created.

 

PS C:\Windows\system32> Add-ClusterServerRole -Name ahmedbc4Dtc1 -Storage "Cluster Disk 7"

Name                                    OwnerNode                                                                 State

----                                    ---------                                                                 -----

ahmedbc4Dtc1                            ahmedbc4-n2                                                              Online

 

PS C:\Windows\system32> Get-ClusterGroup ahmedbc4Dtc1 | Get-ClusterResource | ft -auto

Name                                                State  Group        ResourceType

----                                                -----  -----        ------------

ahmedbc4Dtc1                                        Online ahmedbc4Dtc1 Network Name

Cluster Disk 7                                      Online ahmedbc4Dtc1 Physical Disk

IP Address 157.55.88.0 (3)                          Online ahmedbc4Dtc1 IP Address

IP Address 2001:4898:0:fff:200:5efe:157.55.88.0 (3) Online ahmedbc4Dtc1 IPv6 Tunnel Address

IP Address 2001:4898:f0:1000:: (3)                  Online ahmedbc4Dtc1 IPv6 Address

 

PS C:\Windows\system32> Get-ClusterGroup ahmedbc4Dtc1 | Get-ClusterResource | Get-ClusterResourceDependency | ft -auto

Resource                                            DependencyExpression

--------                                            --------------------

ahmedbc4Dtc1                                        [IP Address 157.55.88.0 (3)] or [IP Address 2001:4898:f0:1000:: ...

Cluster Disk 7

IP Address 157.55.88.0 (3)

IP Address 2001:4898:0:fff:200:5efe:157.55.88.0 (3) ([IP Address 157.55.88.0 (3)])

IP Address 2001:4898:f0:1000:: (3)

 

Notice it is missing the DTC resource.  So, just add that to the group and add the right dependency.  In this case, the DTC resource depends on a disk resource and network name resource as you can see above with the group I created earlier for comparison purposes through the GUI.

 

PS C:\Windows\system32> Get-ClusterGroup ahmedbc4Dtc1 | Add-ClusterResource -Name MSDTC-ahmedbc4Dtc1 -ResourceType "Dist

ributed Transaction Coordinator"

Name                          State                         Group                         ResourceType

----                          -----                         -----                         ------------

MSDTC-ahmedbc4Dtc1            Offline                       ahmedbc4Dtc1                  Distributed Transaction Co...

 

PS C:\Windows\system32> Add-ClusterResourceDependency MSDTC-ahmedbc4Dtc1 ahmedbc4Dtc1

Name                          State                         Group                         ResourceType

----                          -----                         -----                         ------------

MSDTC-ahmedbc4Dtc1            Offline                       ahmedbc4Dtc1                  Distributed Transaction Co...

 

PS C:\Windows\system32> Add-ClusterResourceDependency MSDTC-ahmedbc4Dtc1 "Cluster Disk 7"

Name                          State                         Group                         ResourceType

----                          -----                         -----                         ------------

MSDTC-ahmedbc4Dtc1            Offline                       ahmedbc4Dtc1                  Distributed Transaction Co...

 

PS C:\Windows\system32> Get-ClusterGroup ahmedbc4Dtc1 | Get-ClusterResource | Get-ClusterResourceDependency | ft -auto

Resource                                            DependencyExpression

--------                                            --------------------

ahmedbc4Dtc1                                        [IP Address 157.55.88.0 (3)] or [IP Address 2001:4898:f0:1000:: ...

Cluster Disk 7

IP Address 157.55.88.0 (3)

IP Address 2001:4898:0:fff:200:5efe:157.55.88.0 (3) ([IP Address 157.55.88.0 (3)])

IP Address 2001:4898:f0:1000:: (3)

MSDTC-ahmedbc4Dtc1                                  ([ahmedbc4Dtc1]) and ([Cluster Disk 7])

 

And, now, I’ll online the group.

 

PS C:\Windows\system32> Start-ClusterGroup ahmedbc4Dtc1

Name                                    OwnerNode                                            State

----                                    ---------                                            -----

ahmedbc4Dtc1                            ahmedbc4-n2                                          Online

 

 

That’s all for the group. But, one thing you’ll notice in the Failover Cluster Manager is the difference between the group the GUI created and the one I just created with PowerShell.  Notice the nice icon for the DTC group (icon beside the group name and type on the tabular view in the first diagram) and the “Manage MSDTC” action link (in the second diagram).

 

 

 

The reason this is not the same with the group I created via PowerShell is that I didn’t set the group type for the group properly when I added the DTC resource to the group.

 

PS C:\Windows\system32> gwmi -Namespace root/MSCluster -Class MSCluster_ResourceGroup | ?{ $_.Name -eq "ahmedbc4Dtc" } |

 fl Name,GroupType

Name      : ahmedbc4Dtc

GroupType : 103

 

PS C:\Windows\system32> gwmi -Namespace root/MSCluster -Class MSCluster_ResourceGroup | ?{ $_.Name -eq "ahmedbc4Dtc1" }

| fl Name,GroupType

Name      : ahmedbc4Dtc1

GroupType : 9999

 

To “fix” this up, set the group type via WMI.

 

PS C:\Windows\system32> ( gwmi -Namespace root/MSCluster -Class MSCluster_ResourceGroup | ?{ $_.Name -eq "ahmedbc4Dtc1"

} ).SetGroupType(103)

 

Now, you’re set.

 

 

 

Happy scripting!

 

Regards,

Ahmed Bisht

Senior Program Manager

Clustering & High-Availability

Microsoft