AntiAffinityClassNames is a cluster group property in Windows Failover Clustering used to identify cluster groups that should not be hosted on the same node. When working with clustered Hyper-V environments there is a 1:1 relationship between a cluster group and a virtual machine, and thus we can configure Anti-Affinity for virtual machines using the AntiAffinityClassNames property. For more information, see the links in the resource section in the bottom of the article.
What I want to show in this article is how to configure the AntiAffinityClassNames property using PowerShell. Most articles I have seen in regards to AntiAffinityClassNames covers how to use cluster.exe to configure the property, and since the cluster.exe was deprecated in Windows Server 2008 R2 (it`s still available as a deprecated command) it might be a good idea to learn how to configure this using the new Failover Clustering PowerShell module. In addition you also get other benefits available in PowerShell such as pipelining, export/import to/from different data sources, grouping and so on.
AntiAffinityClassNames is a property of a cluster group, but before we configure the property we need to look at what type it is. We can do this by piping the output of Get-ClusterGroup to the Get-Member cmdlet:
We can see in the definition of the property that it is a System.Collections.Specialized.StringCollection type. This means we can not just pass a text string as the property value, we need to create a object of the correct type. The reason this property is not just a System.String (text string) is that a Cluster Group can have more than one AntiAffinityClassNames values. System.Collections.Specialized.StringCollection has a method called Add which can be used to to add values to the collection. Here is a complete example on how to create such an object, add a couple of values to it and at the end assign it to the AntiAffinityClassNames property of a cluster group:
$value = New-Object System.Collections.Specialized.StringCollection
$value.Add("Domain Controllers")
$value.Add("Infrastructure Server Group")
(Get-ClusterGroup "SCVMM SRV01 Resources").AntiAffinityClassNames = $value
Note that this will overwrite any existing values. As we can see it is not very hard to configure a new value, but it might be harder if you want to preserve existing values remove single items of the existing value and so on. In order to make this easier I have created a PowerShell module which contains 3 script cmdlets for managing AntiAffinityClassNames:
As you can see in the cmdlet help there is support for pipeline input, which makes it possible to configure the AntiAffinityClassNames values based on input such as a CSV-file:
I have also provided examples for the script cmdlets:
Installing the AntiAffinityClassNames module
Download and unzip AntiAffinityClassNames.zip in the following location: %userprofile%DocumentsWindowsPowerShellModulesAntiAffinityClassNames
Alternatively you may save the module in any of the folders in the $Env:PSMODULEPATH variable or import the module from a custom path (Import-Module <path>AntiAffinityClassNames). Here is some more examples to get you started:
# Import the module Import-Module AntiAffinityClassNames # Example usage of the Get-AntiAffinityClassNames script cmdlet Get-AntiAffinityClassNames -Cluster cluster01.domain.local Get-AntiAffinityClassNames -Cluster cluster01.domain.local -ClusterGroup "SC VMM SRV01 Resources" Get-AntiAffinityClassNames -Cluster cluster01.domain.local | Export-Csv -Path c:tempAntiAffinityClassNames_cluster01.csv -NoTypeInformation # Example usage of the Set-AntiAffinityClassNames script cmdlet Set-AntiAffinityClassNames -Cluster cluster01.domain.local -ClusterGroup "SC VMM SRV01 Resources" -Value "Domain Controllers" Set-AntiAffinityClassNames -Cluster cluster01.domain.local -ClusterGroup "SC VMM SRV01 Resources" -Value "Domain Controllers" -Keep Set-AntiAffinityClassNames -Cluster cluster01.domain.local -ClusterGroup "SC VMM SRV01 Resources" -Value "Domain Controllers" -Verbose # Example usage of the Remove-AntiAffinityClassNames script cmdlet Remove-AntiAffinityClassNames -Cluster cluster01.domain.local -ClusterGroup "SC VMM SRV01 Resources" -Clear Remove-AntiAffinityClassNames -Cluster cluster01.domain.local -ClusterGroup "SC VMM SRV01 Resources" -Value "Domain Controllers" Remove-AntiAffinityClassNames -Cluster cluster01.domain.local -ClusterGroup "SC VMM SRV01 Resources" -Value "Domain Controllers" -Verbose
Resources
Failover behavior on clusters of three or more nodes
Understanding Hyper-V Virtual Machine (VM) Failover Policies
Private Cloud: Configuring anti-affinity between VMs on Hyper-V 2008 R2 SP1 and VMM 2012
How to automatically avoid running Exchange VMs on the same Hyper-V server after a host failure
Get started with the Failover Clustering PowerShell-module
Enable Persistent Mode for Cluster Resource Groups using the PowerShell Failover Clustering module