I need to be able to set Anti affinity rules for a bunch of VMs on a SDRS enabled datastore cluster. Does anyone know how to do that?
Thank you very much in advance.
Does this work for you ?
Apply AntiAffinity rule to a new vm
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
I have seen posts like this before, but I am looking to apply it to existing virtual machines. I am using Onyx right now and the code it generates looks really ugly and like I would have to regenerate the entire list every time I create a new VM.
Ok, you are referring to the ConfigureStorageDrsForPod_Task method.
That isn't too hard to use, something like this for example will set SDRS anti-affinity for a specific VM
$storclusterName = "MyStorageCluster"
$vmName = "MyVM"
$storMgr = Get-View StorageResourceManager
$pod = Get-DatastoreCluster -Name $storclusterName
$vm = Get-VM -Name $vmName
$spec = New-Object VMware.Vim.StorageDrsConfigSpec $vmSpec = New-Object VMware.Vim.StorageDrsVmConfigSpec
$vmSpec.operation = "edit"
$vmSpec.info = New-Object VMware.Vim.StorageDrsVmConfigInfo
$vmSpec.info.vm = $vm.ExtensionData.MoRef
$vmSpec.info.enabled = $true
$vmSpec.info.intraVmAffinity = $false
$spec.vmConfigSpec += $vmSpec
$storMgr.ConfigureStorageDrsForPod($pod.ExtensionData.MoRef,$spec,$true)
I'll put that in a function, so you can use it in a pipeline.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Thank you very much. Will that create the rule that will not allow 2 VMs to live on the same datastore?
I am sorry I always get Intra and Inter confused.
No, that will configure the setting if the VMDK for a specific VM will be kept together.
Hold on, I'll give you a function for inter-VM (anti-)affinity as well.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Here you go
$storclusterName = "MyDatastoreCluster"
$vmName1 = "VM1"
$vmName2 = "VM2"
$storMgr = Get-View StorageResourceManager
$pod = Get-DatastoreCluster -Name $storclusterName
$vm1,$vm2 = Get-VM -Name $vmName1,$vmName2
$spec = New-Object VMware.Vim.StorageDrsConfigSpec
$spec.podConfigSpec = New-Object VMware.Vim.StorageDrsPodConfigSpec $rule = New-Object VMware.Vim.ClusterRuleSpec
$rule.operation = "add"
$rule.info = New-Object VMware.Vim.ClusterAntiAffinityRuleSpec
$rule.info.enabled = $true
$rule.info.name = "MyRule"
$rule.info.vm += $vm1.ExtensionData.MoRef,$vm2.ExtensionData.MoRef
$spec.podConfigSpec.rule += $rule
$storMgr.ConfigureStorageDrsForPod($pod.ExtensionData.MoRef,$spec,$true)
This will create a SDRS anti-affinity rule for VM1 and VM2
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Hi LucD,
I am trying to get the values for VM1 & VM2 here . Below is my code . I am trying to disable rules here .
$rules = $dsc.PodStorageDrsEntry.StorageDrsConfig.PodConfig.Rule | Group-Object -Property Name | where {$Rules.Group.Enabled -eq "True"}
foreach ($rule in $Rules.Name) # looping through each rule
{
Write-host "Disabling rule $Rule"
$remRule = New-Object VMware.Vim.ClusterRuleSpec
$remRule.Operation = "edit"
$remRule.Info = New-Object VMware.Vim.ClusterAntiAffinityRuleSpec
$remRule.Info.Name = "$Rule"
$remRule.Info.Enabled = $false
#$remRule.Info.Vm = <How to get the values of vm1 & vm2 here >
#$spec.PodConfigSpec.Rule += $remRule
#$storMgr.ConfigureStorageDrsForPod($dsc.MoRef, $spec, $true)
Below is the variable content for $rules
PS C:\Scripts> $rules
Count Name Group
----- ---- -----
1 Test {VMware.Vim.ClusterAntiAffinityRuleSpec}
1 Lab {VMware.Vim.ClusterAntiAffinityRuleSpec}
Try with
$remRule.Info.Vm = $_.Group[0].VM
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Thank you for the solution, however the rules are not getting disabled . Am I missing something in remove rule $remRule
If you just want disable the rules that are enabled, you could do
$storMgr = Get-View StorageResourceManager
$pod = Get-DatastoreCluster -Name $storclusterName
$spec = New-Object VMware.Vim.StorageDrsConfigSpec
$spec.PodConfigSpec = New-Object VMware.Vim.StorageDrsPodConfigSpec
$pod.ExtensionData.PodStorageDrsEntry.StorageDrsConfig.PodConfig.Rule |
where{$_.Enabled} |
ForEach-Object -Process {
Write-Host "Disabling rule $($_.Name)"
$rule = New-Object vmware.vim.ClusterRuleSpec
$rule.Info = $_
$rule.Info.Enabled = $false
$rule.Operation = [vmware.vim.ArrayUpdateOperation]::edit
$spec.PodConfigSpec.Rule += $rule
}
$storMgr.ConfigureStorageDrsForPod($pod.ExtensionData.MoRef,$spec,$true)
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Hi LucD,
Now I am getting below error as :
Disabling rule Lab
You cannot call a method on a null-valued expression.
At C:\Scripts\sDRSconfig.ps1:47 char:1
+ $storMgr.ConfigureStorageDrsForPod($dsc.MoRef, $spec, $true)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
Below is the script :
Clear-Host
# Importing csv with columns for vCenter and sDRS Cluster
Import-Csv -Path .\test.csv -UseCulture | Group-Object -Property vCenter -PipelineVariable vc |
ForEach-Object -process {
#Write-Host "Connecting vCenter:" $vc.Name -ForegroundColor Cyan
#Connect-VIServer -Server $vc.Name
$storResMgr = Get-View StorageResourceManager
$spec = New-Object VMware.Vim.StorageDrsConfigSpec
$spec.podConfigSpec = New-Object VMware.Vim.StorageDrsPodConfigSpec
foreach($clus in $vc.Group.'sDRS Cluster Name') # sDRS Cluster column name is "sDRS Cluster Name"
{
$dsc = Get-DatastoreCluster -Name $clus | Get-View
#$dsc.UpdateViewData()
$dsc | Group-Object -Property Name |
ForEach-Object -Process{
<#$SpaceSpec = New-Object VMware.Vim.StorageDrsSpaceLoadBalanceConfig
$IoSpec = new-object VMware.Vim.StorageDrsIoLoadBalanceConfig
$spec.podConfigSpec.Enabled = $true
$spec.podConfigSpec.DefaultVmBehavior = 'automated'
[int]$SpaceSpec.SpaceUtilizationThreshold = '80'
$spec.PodConfigSpec.SpaceLoadBalanceConfig = $SpaceSpec
[int]$IoSpec.IoLatencyThreshold = '15'
$spec.PodConfigSpec.IoLoadBalanceConfig = $IoSpec
$storResMgr.ConfigureStorageDrsForPod($dsc.MoRef, $spec, $true)#>
if ($dsc.PodStorageDrsEntry.StorageDrsConfig.PodConfig.Rule.Count -ne '0')
{
$dsc.PodStorageDrsEntry.StorageDrsConfig.PodConfig.Rule | where{$_.Enabled -eq "true"} |
ForEach-Object -Process {
Write-Host "Disabling rule $($_.Name)"
$Remrule = New-Object vmware.vim.ClusterRuleSpec
$Remrule.Info = $_
$Remrule.Info.Enabled = $false
$Remrule.Operation = [vmware.vim.ArrayUpdateOperation]::edit
$spec.PodConfigSpec.Rule += $remRule
$storMgr.ConfigureStorageDrsForPod($dsc.MoRef, $spec, $true)
}
}
else {Write-Host "No Rules found in "$_.Name""}
}
}
}
#Disconnect-VIServer -Server $vc.Name -Confirm:$false
Try chaning this line line
$storResMgr = Get-View StorageResourceManager
to
$storMgr = Get-View StorageResourceManager
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Ohh... that was a silly one ! Thank You LucD !