Lately I have been working on a number of virtualization projects which make use of VMware vSphere Metro Storage Clusters (vMSC). With most of these types of implementations, virtual machines must be pinned to a preferred site to minimise impact to virtual machines in the event of a site failure. DRS groups are the most common way to achieve this, however I was wanting to find a way to automate the add/remove of virtual machines based on each VM’s datastore location.
To begin, I configured each of the datastores with a prefix of the site which was its preferred site, e.g. DC1-VMFS-01 or DC2-VMFS-01. I then placed VMs on a datastore which corresponded to their preferred site.
With the help of DRSRule I was then able to create two PowerCLI functions to automate the process to add the VMs to a corresponding DRS VM group based on their datastore location. The function can be used with a datastore name, prefix or suffix.
function Add-DrsVMToDrsVMGroup{ #Requires -Modules VMware.VimAutomation.Core, DRSRule #region script help <# .SYNOPSIS Adds virtual machines to a DRS VM group based on datastore location .DESCRIPTION Adds virtual machines to a DRS VM group based on datastore location .NOTES Version: 1.0 Author: Tim Carman Twitter: @tpcarman Github: tpcarman .LINK https://github.com/tpcarman/PowerCLI-Scripts .PARAMETER DrsVMGroup Specifies the DRS VM Group This parameter is mandatory but does not have a default value. .PARAMETER Cluster Specifies the cluster which contains the DRS VM Group This parameter is mandatory but does not have a default value. .PARAMETER Prefix Specifies a prefix string for the datastore name This parameter is optional and does not have a default value. .PARAMETER Suffix Specifies a suffix string for the datastore name This parameter is optional and does not have a default value. .PARAMETER Datastore Specifies a datastore name This parameter is optional and does not have a default value. .EXAMPLE Add-DrsVMtoDrsVMGroup -DRSVMGroup 'SiteA-VMs' -Cluster 'Production' -Prefix 'SiteA-' .EXAMPLE Add-DrsVMtoDrsVMGroup -DRSVMGroup 'SiteA-VMs' -Cluster 'Production' -Suffix '-02' .EXAMPLE Add-DrsVMtoDrsVMGroup -DRSVMGroup 'SiteB-VMs' -Cluster 'Production' -Datastore 'VMFS-01' #> #endregion script help #region script parameters [CmdletBinding()] Param( [Parameter(Mandatory=$True,HelpMessage='Specify the name of the DRS VM Group')] [ValidateNotNullOrEmpty()] [String]$DrsVMGroup='', [Parameter(Mandatory=$True,HelpMessage='Specify the cluster name')] [ValidateNotNullOrEmpty()] [String]$Cluster='', [Parameter(Mandatory=$False,ParameterSetName=’Prefix’,HelpMessage='Specify the prefix string for the datastore name')] [ValidateNotNullOrEmpty()] [String]$Prefix='', [Parameter(Mandatory=$False,ParameterSetName=’Suffix’,HelpMessage='Specify the suffix string for the datastore name')] [ValidateNotNullOrEmpty()] [String]$Suffix='', [Parameter(Mandatory=$False,ParameterSetName=’Datastore’,HelpMessage='Specify the datastore name')] [ValidateNotNullOrEmpty()] [String]$Datastore='' ) #endregion script parameters #region script body if($Prefix){ $VMs = Get-Datastore | where{($_.name).StartsWith($Prefix)} | Get-VM } if($Datastore){ $VMs = Get-Datastore | where{($_.name) -eq $Datastore} | Get-VM } if($Suffix){ $VMs = Get-Datastore | where{($_.name).EndsWith($Suffix)} | Get-VM } $objDrsVMGroup = Get-DrsVMGroup -Name $DrsVMGroup -Cluster $Cluster foreach($VM in $VMs){ if(($objDrsVMGroup).VM -notcontains $VM){ Write-Host "Adding virtual machine $VM to DRS VM Group $DrsVMGroup" try{ Set-DrsVMGroup -Name $DrsVMGroup -Cluster $Cluster -Append -VM $VM } catch{ Write-Error "Error adding virtual machine $VM to DRS VM Group $DrsVMGroup" } } } #endregion script body }