How to configure Start Order Priority for Clustered VMs0
Have you ever wanted to be able to prioritize the order in which your virtual machines start up in a Hyper-V cluster? I bet you do, and ever since Windows server 2012, Microsoft introduced the Startup Priority feature for virtual machines, but in server 2016 we have new improvements as you will see later on. Before this, every time one of our Hyper-V hosts failed, the virtual machines that were running on this host were all started simultaneous on other hosts in the cluster. This behavior was not wanted because there are servers like domain controllers, database servers or virtual firewalls that need to start before other virtual machines. Also, you might not want to start some of the virtual machines but instead leave them powered off because of low cluster resources.
Now you might ask: Why not use the Automatic Start Actions option? You are right, we can configure VMs to start in a particular order by setting up a startup delay (in seconds) for each one of them. So, for a domain controller we can set up a Startup Delay of 0 seconds, for a database server a delay of 60 seconds, and for a web server a delay of 120 seconds. The VMs will start in this order and they will work fine if they are running on a single host. If there is a cluster, like in this lab, or in your production environment, the Startup Delay settings will be reset to their defaults (Nothing option) once the machine is migrated to another host in the cluster.
As you can tell, this option is not suited for environments where Hyper-V hosts are joined to a Failover Cluster. This leaves us only with the Startup Priority function, which was continued in Hyper-V server 2016. There are four priority options that we can designate to our VMs: Low (1000), Medium (2000), High (3000) and No Auto Start (0). I know the last one is not necessarily a priority since it leaves the VMs in a power off state, but its part of this feature, so I had to mention it.
Setting up VMs Startup Priority
Now, configuring the Start Priority for our VMs is just a matter of a few mouse clicks. Open the Failover Cluster Manager console, select the VM or the VMs that you want to modify start priorities for. Right-click each one and choose Change Startup Priority from the menu. You can also use the same option from the Actions pane. As you can see below, here we have the options I mentioned above, where High means the VM(s) will start first and Low means the VM(s) will start last. By default all VMs are set to Medium, so they all heave the same priority (2000).
For those that want to use PowerShell, it can be done using a single line of code; but first, let’s view the priority of the VMs:
Get-ClusterGroup -Name * | fl name,priority
The second command will be to change the startup priority of the VMs using the numbers mentioned above. Of course, you can adjust or improve the command as you know best and as it fits in your environment, but don’t forget to share it with the community in the comments area below this post! As a first example I’ve modified the startup priority of a single VM from High to Low.
Testing VMs Startup Priority
Once everything is set up, we can move along to the testing phase. For this I moved most of my VMs to a single host then pulled the plug.
The VMs that were configured with the No Auto Start option will be in an off state after the migration. The rest of them will start based off of their Startup Priority.
All this is good, but as I’ve said in the beginning of the article, server 2016 comes with new improvements. Using PowerShell, and only PowerShell (for now) we can create a so called Cluster Group Set. With this we can group virtual machines, then create dependencies between a Cluster Group Set and other virtual machines or between multiple Cluster Group Sets. Imagine we have a few domain controllers, a database server, a web server and maybe software firewall. We can group the domain controllers together and create a Cluster Group Set or “set” for short, then group the database servers together and create another set that contains only the database servers and so on. After we created the sets we can configure the dependency between them so the domain controller’s set will start first then continue with the database servers, web servers etc…
In order for us to accomplish this, Microsoft created new PowerShell cmdlets:
To create and manage the Cluster Group Sets
To manage the group dependency
To manage Group Set dependency
These cmdlets are only available if the Hyper-V hosts are part of a Failover Cluster. They do not work on stand-alone hosts; actually they are not even available.
Creating and managing the sets
To create a set or sets we are going to use the New-ClusterGroupSet cmdlet.
#Naming the cluster
$HVCluster = "HyperV-HA.vkernel.local"
New-ClusterGroupSet -CimSession $HVCluster -Name "DomainControllers"
New-ClusterGroupSet -CimSession $HVCluster -Name "SQLServers"
New-ClusterGroupSet -CimSession $HVCluster -Name "ExchangeOWA"
New-ClusterGroupSet -CimSession $HVCluster -Name "Firewalls"
Now that we created the sets it’s time to add virtual machines to their respective Cluster Group Set. We are going to add our domain controllers to the DomainControllers set, the SQL servers to the SQLServers set, and so on.
#Add Cluster Group VMs to Set
#Domain Controllers VMs
Add-ClusterGroupToSet -CimSession $HVCluster -Name DomainControllers -Group "Server-DC01"
Add-ClusterGroupToSet -CimSession $HVCluster -Name DomainControllers -Group "Server-DC02"
Add-ClusterGroupToSet -CimSession $HVCluster -Name DomainControllers -Group "Server-DC03"
#SQL Server VMs
Add-ClusterGroupToSet -CimSession $HVCluster -Name SQLServers -Group "Server-SQL01"
Add-ClusterGroupToSet -CimSession $HVCluster -Name SQLServers -Group "Server-SQL02"
#Exchange OWA Server VMs
Add-ClusterGroupToSet -CimSession $HVCluster -Name ExchangeOWA -Group "Ex-OWA01"
Add-ClusterGroupToSet -CimSession $HVCluster -Name ExchangeOWA -Group "Ex-OWA02"
#Appliance Firewall VMs
Add-ClusterGroupToSet -CimSession $HVCluster -Name Firewalls -Group "Firewall"
Now if we execute the Get-ClusterGroupSet command we can see our VMs being part of a set or Cluster Group Set.
The last command that we need to run is the one that creates the dependencies. In this example we are going to create dependencies between the sets we set-up earlier.
Add-ClusterGroupSetDependency -CimSession $HVCluster -Name Firewalls -Provider ExchangeOWA
Add-ClusterGroupSetDependency -CimSession $HVCluster -Name ExchangeOWA -Provider SQLServers
Add-ClusterGroupSetDependency -CimSession $HVCluster -Name SQLServers -Provider DomainControllers
Testing the Cluster Group Set dependency
For this we need to have all our VMs in a shut down state, then right-click one of them and choose Start. As you can see the domain controller will start first since all the the other VMs are dependent of them. After 20 second (default wait time) then next set will be powered on. No matter what VM you power on, it will only start after it’s dependent VM or VMs will start.
All this looks good on the surface, but during my testing I noticed that it doesn’t always work. When I started one of my SQL servers VMs it did not start the rest of the machines in the upper sets, only the domain controllers on which it was dependent on. I thought the Exchange servers and the firewall appliance would start too, but that didn’t happened. I don’t know if this is the way Microsoft intended it to work, or if there is something I’m missing in the implementation; but I’ll leave it to you and maybe your experience will be different. It is a VERY new feature after all. Also, feel free to tell us your thoughts about sets in the comments area or even tell us about your experience with them!
Have any questions or feedback?
Leave a comment below!