When Windows Server 2016 was released Microsoft brought us a new feature I personally have been waiting for since I first started with Hyper-V on Windows Server 2008 R2. That feature is Virtual Machine Start Ordering.
What is Virtual Machine Start Ordering?
Virtual Machine Start Ordering enables us to make dependencies between VMs or Groups of VMs to make sure that they start in the correct order. Let’s imagine we have a three-tier application that uses web servers, database servers and identity servers. If all the VMs were off due to a failure and we tried to start the web servers, thanks to Virtual Machine Start Ordering and dependencies the identity servers would start and then the database servers and finally the web servers. All this just by starting one web server. Now, how cool is that?
The Functions and Cmdlets
This new feature can only be managed by PowerShell. To get a list of the new PowerShell CMDLets open an elevated PowerShell window and type:
Get-Command “ClusterGroup”
You will notice ClusterGroup in every command. So what is a Cluster Group? A Cluster Group is just a Cluster role, such as Virtual Machine, DHCP server, etc. A Set is a group of one or more Virtual Machines usually a group of servers doing the same thing, like databases.
Functions to manage Sets
New-ClusterGroupSet: Creates a new Set
Get-ClusterGroupSet: Gets information about Sets
Set-ClusterGroupSet: Edits a Set
Remove-ClusterGroupSet: Removes a Set
Add-ClusterGroupToSet: Add Cluster Group to a Set
Remove-ClusterGroupFromSet: Remove Cluster Group from a Set
Functions to manage dependencies for a Cluster Group
Add-ClusterGroupSetDependency: Add a dependency
Get-ClusterGroupSetDependency: Lists current dependencies
Remove-ClusterGroupSetDependency: Removes a dependency
Cmdlets to manage Cluster Groups (VMs and cluster resources)
Add-ClusterGroup: Create a Cluster Group
Get-ClusterGroup: List all current Cluster Groups
Move-ClusterGroup: Move Cluster Group to different host
Remove-ClusterGroup: Removes Cluster Group
Start-ClusterGroup: Starts Cluster Group
Stop-ClusterGroup: Stops Cluster Group
Create Cluster Group Sets
To create the Sets we are going to use the below PowerShell. For this article, I am creating three Sets called, Identity, Database and Web.
#Cluster Name
$Cluster="PIXEL-CLUSTER"
#Create Cluster Group SET (Identity)
New-ClusterGroupSet -CimSession $Cluster -Name "Identity Set 1" -Verbose
#Create Cluster Group SET (Database)
New-ClusterGroupSet -CimSession $Cluster -Name "Database Set 1" -Verbose
#Create Cluster Group SET (Web)
New-ClusterGroupSet -CimSession $Cluster -Name "Web Set 1" -Verbose
#List Cluster Group SET
Get-ClusterGroupSet -CimSession $Cluster | ft Name, StartupCount, StartupDelaytrigger -AutoSize
In the above image, you will notice that we have the default settings for StartupCount and StartupDelayTrigger. To correct this we use the following PowerShell.
#Set properties for VM SETS
Set-ClusterGroupSet -CimSession $Cluster -Name "Identity Set 1" -IsGlobal 1 -Verbose
Set-ClusterGroupSet -CimSession $Cluster -Name "Database Set 1" -StartupDelayTrigger Online -StartupCount 0 -Verbose
Set-ClusterGroupSet -CimSession $Cluster -Name "Web Set 1" -StartupDelayTrigger Online -StartupCount 0 -Verbose
#List Cluster Group SET
Get-ClusterGroupSet -CimSession $Cluster | ft Name, StartupCount, StartupDelaytrigger -AutoSize
In the above code, you will see that we have set the Identity Set 1 group to Global. Global is used for groups you want to start before any other group. This is mostly used for Domain Controllers, DNS Servers etc. For the other two groups, we have set StartupDelayTrigger to Online. This means the group will wait until the group has reached an online state. You could use Delay, which is the default. This will allow you to define how many seconds the group should wait before it starts. The default is 20. If you want to change that you can use the StartupDelay switch and set the value you want.
The last switch I have used is StartupCount. This defines the number of Cluster Groups in a set that needs to be Online or passed the Delay Count before the set is considered to be started. I have used the option 0. This means that as long as the majority of the groups in a set are started then it will move onto the next set. You can also use the default option, which is -1. This will mean that all groups in a set must be in a started state before the process moves on. You can also put a user-defined number in, but be aware that if the number you choose is greater than the number of groups in the set then it will wait for all groups to start.
Adding Cluster Group to Sets
Now we can add Virtual Machines cluster groups to our newly created Sets. To do this we can use the following PowerShell.
#Add single Cluster Group (VM) to SET
Add-ClusterGroupToSet -CimSession $Cluster -Name "Identity Set 1" -Group "DC01" -Verbose
#Add single Cluster Group (VM) to SET
Add-ClusterGroupToSet -CimSession $Cluster -Name "Database Set 1" -Group "DB01" -Verbose
#Add Multiple Cluster Groups (VMs) to a SET
Add-ClusterGroupToSet -CimSession $Cluster -Name "Web Set 1" -Group "WEB01" -Verbose
Add-ClusterGroupToSet -CimSession $Cluster -Name "Web Set 1" -Group "WEB02" -Verbose
#List Cluster Group SET
Get-ClusterGroupSet -CimSession $Cluster | ft Name, GroupNames, StartupCount, StartupDelaytrigger -AutoSize
In the above image, you will be able to see what Cluster Groups we have in each Set. This is shown in the Group Names column. As you can see you can have just one Cluster Group in a Set and can add more at any time using the Add-ClusterGroupToSet Cmdlet.
Setting Dependencies
Now that we have the Set groups setup we now have to configure the dependency between the new Sets. To do this we can use the following PowerShell.
#Set Dependancy Between SETs
Add-ClusterGroupSetDependency -CimSession $Cluster -Name "WEB SET 1" -Provider "Database Set 1" -Verbose
#Set Dependancy between VM and SET
Add-ClusterGroupSetDependency -CimSession $Cluster -Name "Database Set 1" -Provider "Identity Set 1" -Verbose
#List Cluster Group SET
Get-ClusterGroupSet -CimSession $Cluster | ft Name, GroupNames, ProviderNames, StartupDelaytrigger, StartupCount -AutoSize
So, in the above image, you will notice that I have the Database set 1 dependent on the Identity Set 1 being online before it can start. You will also see that Web Set 1 needs the Database Set 1 to be online before it can start. Now if all of the VM’s were offline and I started Web01, then DC01 would start first, followed by DB01 and then finally Web01. Web02 would stay offline due to StartupCount being set to majority.
I hope you found this article helpful. If you have any questions please leave a comment and I will get back to you.
Read More: