Skip to content

Instantly share code, notes, and snippets.

@techdecline
Created October 25, 2021 13:28
Show Gist options
  • Select an option

  • Save techdecline/071ad29feff4aff461f83774d85fd3f2 to your computer and use it in GitHub Desktop.

Select an option

Save techdecline/071ad29feff4aff461f83774d85fd3f2 to your computer and use it in GitHub Desktop.
Create new VMware vSphere DRS Groups and Rules
[cmdletbinding()]
param (
# vCenter Name
[Parameter(Mandatory)]
[ValidateScript({Test-NetConnection -ComputerName $_ -Port 443})]
[string]
$vCenterName,
# vCenter Credentials
[Parameter(Mandatory)]
[pscredential]
$Credential,
# VM Name Filter
[Parameter(Mandatory=$false)]
[string]
$VMNameFilter = "-(p|c)-",
# Exclude Name Filter
[Parameter(Mandatory=$false)]
[string]$Exclude = "^NTNX.*",
# Virtual Machine Tag
[Parameter(Mandatory)]
[string]$VMTag,
# Host Tag
[Parameter(Mandatory)]
[string]$HostTag,
# Tag Category
[Parameter(Mandatory=$false)]
[string]$TagCategory = "Workload",
# DRS Rule Type
[Parameter(Mandatory=$false)]
[string]$DrsRuleType = "ShouldRunOn",
# Enabled Rule
[Parameter(Mandatory=$false)]
[bool]$EnableRule = $false,
# Log File Path
[Parameter(Mandatory=$false)]
[String]$LogFilePath = $env:TEMP
)
begin {
try {
Import-Module VMware.PowerCLI -errorAction Stop
Import-Module LogStream
}
catch [System.Management.Automation.ActionPreferenceStopException] {
Write-Error "Go fix your PowerCLI Installation: $($error[0].Exception.Message)"
}
$logFile = Join-Path $LogFilePath -ChildPath "Assign-DrsRules_$(Get-Date -Format yyyyMMdd).log"
Start-Log -LogFilePath $logFile
Set-PowerCLIConfiguration -InvalidCertificateAction Ignore -ParticipateInCeip $false -confirm:$false
$null = Connect-VIServer -Server $vCenterName -credential $Credential
Write-VerboseLog -LogFilePath $logFile -Message "Connected VCenter $vCenterName with Credentials $($cred.UserName)"
}
process{
# Fetch vCenter Cluster
$cluster = Get-Cluster -server $vCenterName
Write-VerboseLog -LogFilePath $logFile -Message "Processing cluster: $($cluster)"
# Initialize DrsGroupNames
$drsVmGroupName = "$($HostTag)_VM"
$drsHostGroupName = "$($VMTag)_Hosts"
# Initialize Host and VM Collections
$targetHostArr = [System.Collections.ArrayList]@()
$targetVmArr = [System.Collections.ArrayList]@()
#Initiate existence variables
$vmTagExists = $false
$hostGroupExists = $false
$vmGroupExists = $false
#Check if DRS groups exists
$drsHostGroup = Get-DrsClusterGroup -Cluster $cluster -Type VMHostGroup -Name $drsHostGroupName -ErrorAction SilentlyContinue
$drsVMGroup = Get-DrsClusterGroup -Cluster $cluster -Type VMGroup -Name $drsVmGroupName -ErrorAction SilentlyContinue
if($drsHostGroup){
Write-VerboseLog -LogFilePath $logFile -Message "DRS host group found"
$hostGroupExists = $true
}
if($drsVMGroup){
Write-VerboseLog -LogFilePath $logFile -Message "DRS VM group found"
$vmGroupExists = $true
}
#########
# Hosts #
#########
#Retrieve Connected hosts and check if the tag exists
$vmhosts = $cluster | Get-VMHost -State Connected
foreach($vmhost in $vmhosts){
$hostTagAssigned = $vmhost | Get-TagAssignment -Category $TagCategory -ErrorAction SilentlyContinue
if($hostTagAssigned){
foreach($hosttagA in $hostTagAssigned){
if($hosttaga.Tag.Name -eq $HostTag){
Write-VerboseLog -LogFilePath $logFile -Message "Adding Host to Target Collection: $($vmhost.Name)"
$null = $targetHostArr.add($vmhost)
$hostTagExists = $true
}
}
}
}
#Create Host Group if tag is found and group is not found
if(!$hostGroupExists -and $hostTagExists -and $targetHostArr -ne $null){
#Create DRS group
Write-VerboseLog -LogFilePath $logFile -Message "Creating DRS Host group"
New-DrsClusterGroup -Name $drsHostGroupName -Cluster $cluster -VMHost $targetHostArr
$drsHostGroup = Get-DrsClusterGroup -Cluster $cluster -Type VMHostGroup -Name $drsHostGroupName -ErrorAction SilentlyContinue
if($drsHostGroup){
$hostGroupExists = $true
}
}
else{
Write-VerboseLog -LogFilePath $logFile -Message "Host tag doesn't exist, no need for the group."
}
#Check if Hosts are a member of the DRS group
if($hostGroupExists -and $hostTagExists){
foreach($targetHost in $targetHostArr){
if(!$drsHostGroup.Member.Contains($targetHost)){
Write-VerboseLog -LogFilePath $logFile -Message "Adding Host to Host Group: $($targetHost.Name)"
$null = $drsHostGroup | Set-DrsClusterGroup -Add -VMHost $targetHost
}
}
}
#########
# VMs #
#########
#Retrieve vms and check if the tag exists
$vms = $cluster | Get-VM | Where-Object {$_.Name -match $VMNameFilter -and $_.Name -notmatch $Exclude}
foreach($vm in $vms){
$vmTagAssigned = $vm | Get-TagAssignment -Category $TagCategory
if($vmTagAssigned){
foreach($vmtagA in $vmTagAssigned){
if($vmtagA.Tag.Name -eq $VMTag){
Write-VerboseLog -LogFilePath $logFile -Message "VM has been added to list of target VM: $($vm.Name)"
$null = $targetVmArr.add($vm)
$vmTagExists = $true
}
}
}
}
#Create SQL VM Group if tag is found and group is not found
if(!$vmGroupExists -and $vmTagExists -and $targetVmArr -ne $null){
Write-VerboseLog -LogFilePath $logFile -Message "Creating DRS VM group: $drsVmGroupName"
New-DrsClusterGroup -Name $drsVmGroupName -Cluster $cluster -VM $targetVmArr
$drsVMGroup = Get-DrsClusterGroup -Cluster $cluster -Type VMGroup -Name $drsVmGroupName -ErrorAction SilentlyContinue
if($drsVMGroup){
$vmGroupExists = $true
}
}
else{
Write-VerboseLog -LogFilePath $logFile -Message "VM tag doesn't exist, no need for the group."
}
#Check if VM are a member of the DRS group
if($vmGroupExists -and $vmTagExists){
foreach($targetVM in $targetVmArr){
if(!$drsVMGroup.Member.Contains($targetVM)){
Write-VerboseLog -LogFilePath $logFile -Message "Adding VM to DRS Group"
$drsVMGroup | Set-DrsClusterGroup -Add -VM $targetVM
}
}
}
############
# DRS Rule #
############
$ruleName = "DRS_$($VMTag)_$($HostTag)_$($DrsType)"
#Check DRS Rule
if($hostGroupExists -and $vmGroupExists){
$drsRules = Get-DrsVMHostRule -Cluster $cluster -Type $DrsRuleType -VMHostGroup $drsHostGroup -VMGroup $drsVMGroup
if(!$drsRules){
Write-VerboseLog -LogFilePath $logFile -Message "Creating DRS rule: $ruleName"
New-DrsVMHostRule -Name $ruleName -Cluster $cluster -VMHostGroup $drsHostGroup -VMGroup $drsVMGroup -Type $DrsRuleType -Enabled:$EnableRule
}
}
}
end {
Stop-Log -LogFilePath $logFile
Disconnect-VIServer -Server $vCenterName -confirm:$false
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment