VMware Cloud Community
jondercik2
Contributor
Contributor

Set datastore cluster IntraVM affinity rules

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.

Reply
0 Kudos
13 Replies
LucD
Leadership
Leadership

Does this work for you ?

Apply AntiAffinity rule to a new vm


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
jondercik2
Contributor
Contributor

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.

Reply
0 Kudos
LucD
Leadership
Leadership

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

Reply
0 Kudos
jondercik2
Contributor
Contributor

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.

Reply
0 Kudos
LucD
Leadership
Leadership

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

Reply
0 Kudos
LucD
Leadership
Leadership

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

Reply
0 Kudos
Xecutioner0
Contributor
Contributor

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}

Reply
0 Kudos
LucD
Leadership
Leadership

Try with

$remRule.Info.Vm = $_.Group[0].VM


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
Xecutioner0
Contributor
Contributor

Thank you for the solution, however the rules are not getting disabled . Am I missing something in remove rule $remRule

Reply
0 Kudos
LucD
Leadership
Leadership

If you just want disable the rules that are enabled, you could do

$storclusterName = "MyStorageCluster"

$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

Reply
0 Kudos
Xecutioner0
Contributor
Contributor

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

Reply
0 Kudos
LucD
Leadership
Leadership

Try chaning this line line

$storResMgr = Get-View StorageResourceManager

to

$storMgr = Get-View StorageResourceManager


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Xecutioner0
Contributor
Contributor

Ohh... that was a silly one ! Thank You LucD​ !

Reply
0 Kudos