Separate VM in Hyper-V virtual machines using anti-affinity

For some Virtual machines you don’t want to run them on the same hyper-v server in a cluster. If you have a two node cluster and running two DC’s you don’t want to run the VM’s on the same hyper-v box. With anti-affinity you can prevent this that both VM’s are running on the same box. But this is not the same as preferred owner. With the preferred owner you prevent that the VM will failover to a other Hyper-v host. If the hyper-v host is failing so are all the VM’s on this host there will be no failover to an other Hyper-v host.


With the anti-affinity you create a “rule” that says he these two VM’s or cluster roles may never be seen on the same hyper-v host. unless there is no other way.

Anti-Affinity – For a given VM (technically any cluster Group) there is a cluster group property called AntiAffinityClassNames that allows you to configure the preference to attempt to keep that VM off the same node as other similar VMs. Let’s say for example you have two domain controllers running in VMs. It would probably be best to keep those running on different nodes if possible. When determining failover, the cluster service will deprioritize any node which is hosting a similar VM. If there is no other option (in the goal of making VMs available) it will place them on the same host. More information:

But there is no GUI option for this. PowerShell only and this need settings on all your hyper-v nodes in the cluster. So get some listing of the classes Get-ClusterGroup | get-member -name AntiAffinityClassNames these are the objects “System.Object AntiAffinityClassNames {get;set;}”

If you need more info check this link :


With a quick check we can see the current affinity settings

Get-ClusterGroup | Select AntiAffinityClassNames


Currently there are no rules in place. Because I need to run this on all servers I create a nice step by step and easy to change Powershell script I create several groups names  SQL,VM,DC,APP now I know what machines I can place in the groups.

So I create a small amount of variables:

$SQLAntiAffinity = New-Object System.Collections.Specialized.StringCollection

$SQLAntiAffinity.Add(“SQL Server Instance”)

$DCAntiAffinity = New-Object System.Collections.Specialized.StringCollection

$DCAntiAffinity.Add(“Domain Controllers”)

$WEBAntiAffinity = New-Object System.Collections.Specialized.StringCollection

$WEBAntiAffinity.Add(“WEB Servers”)

$APPAntiAffinity = New-Object System.Collections.Specialized.StringCollection

$APPAntiAffinity.Add(“Application Servers”)


The last part is assign the VM to the group.

(Get-ClusterGroup –Name VMSQL01).AntiAffinityClassNames = $SQLAntiAffinity

(Get-ClusterGroup –Name VMSQL02).AntiAffinityClassNames = $SQLAntiAffinity

(Get-ClusterGroup –Name VMDC01).AntiAffinityClassNames = $DCAntiAffinity

(Get-ClusterGroup –Name VMDC02).AntiAffinityClassNames = $DCAntiAffinity

(Get-ClusterGroup –Name VMWEB01).AntiAffinityClassNames = $WEBAntiAffinity

(Get-ClusterGroup –Name VMWEB02).AntiAffinityClassNames = $WEBAntiAffinity

(Get-ClusterGroup –Name VMAPP01).AntiAffinityClassNames = $APPAntiAffinity

(Get-ClusterGroup –Name VMAPP02).AntiAffinityClassNames = $APPAntiAffinity

And You did know you can use the + = to add a VM to the group or Clear the group (Get-ClusterGroup –Name NEWVM01).AntiAffinityClassNames += $SQLAntiAffinity or clear the VM from all Groups (Get-ClusterGroup –Name NEWVM01).AntiAffinityClassNames = “” the rules are in place lets see if we can find them back Get-ClusterGroup |Select-Object -Property name,AntiAffinityClassNames


(Get-ClusterGroup demo01).AntiAffinityClassNames

Now that the roles are in place We can see how It works. I paused a hyper-v node and As soon as I resume the node the anti-affinity rule kicks the VM Winking smile


It's only fair to share...Tweet about this on TwitterShare on LinkedIn0Share on Google+0Share on Facebook6