broedi
Contributor
Contributor

How to modify an existing Virtual Machine DRS -Group?

Jump to solution

Hi,

I use DRS-Rules to place VMs to a Group of selected Hosts within a Cluster.

The poblem is, that I didn't find any methods to modify (add new VMs) to an existing "Virtual Machine DRS Group".

AFAIK, the configuration is stored under  $ClusterView.ConfigurationEx.Group

Any ideas?

Thanks!

1 Solution

Accepted Solutions
RvdNieuwendijk
Leadership
Leadership

Hi Willibald,

I did some investigation in the VMware vSphere SDK and made two functions Get-DrsGroup and Add-VmToDrsGroup to add one or more virtual machines to a ClusterVmGroup. Some examples of how to use these function are in the code. If you have added these functions to your PowerCLI session, you can use Get-Help to get information about these functions. And also to get the examples. E.g. Get-Help Add-VmToDrsGroup -Full.

Function Get-DrsGroup {
<#
.SYNOPSIS
Retrieves DRS groups from a cluster.

.DESCRIPTION
Retrieves DRS groups from a cluster.

.PARAMETER Cluster
Specify the cluster for which you want to retrieve the DRS groups

.PARAMETER Name
Specify the name of the DRS group you want to retrieve.

.EXAMPLE
Get-DrsGroup -Cluster $Cluster -Name "VMs DRS Group"
Retrieves the DRS group "Vms DRS Group" from cluster $Cluster.

.EXAMPLE
Get-Cluster | Get-DrsGroup
Retrieves all the DRS groups for all clusters.

.INPUTS
ClusterImpl

.OUTPUTS
ClusterVmGroup
ClusterHostGroup

.COMPONENT
VMware vSphere PowerCLI
#>

  param([parameter(Mandatory=$true, ValueFromPipeline=$true)]$Cluster,
        [string] $Name="*")

  process {
    $Cluster = Get-Cluster -Name $Cluster
    if($Cluster) {
      $Cluster.ExtensionData.ConfigurationEx.Group | `
      Where-Object {$_.Name -like $Name}
    }
  }
}
  
Function Add-VMToDrsGroup {
<#
.SYNOPSIS
Adds a virtual machine to a cluster VM DRS group.

.DESCRIPTION
Adds a virtual machine to a cluster VM DRS group.

.PARAMETER Cluster
Specify the cluster for which you want to retrieve the DRS groups

.PARAMETER DrsGroup
Specify the DRS group you want to retrieve.

.PARAMETER VM
Specify the virtual machine you want to add to the DRS Group.

.EXAMPLE
Add-VMToDrsGroup -Cluster $Cluster -DrsGroup "VM DRS Group" -VM $VM
Adds virtual machine $VM to the DRS group "VM DRS Group" of cluster $Cluster.

.EXAMPLE
Get-Cluster MyCluster | Get-VM "A*" | Add-VMToDrsGroup -Cluster MyCluster -DrsGroup $DrsGroup
Adds all virtual machines with a name starting with "A" in cluster MyCluster to the DRS group $DrsGroup of cluster MyCluster.

.INPUTS
VirtualMachineImpl

.OUTPUTS
Task

.COMPONENT
VMware vSphere PowerCLI
#>

  param([parameter(Mandatory=$true)] $Cluster,
        [parameter(Mandatory=$true)] $DrsGroup,
        [parameter(Mandatory=$true, ValueFromPipeline=$true)] $VM)
        
  begin {
    $Cluster = Get-Cluster -Name $Cluster
  }
  
  process {
    if ($Cluster) {
      if ($DrsGroup.GetType().Name -eq "string") {
        $DrsGroupName = $DrsGroup
        $DrsGroup = Get-DrsGroup -Cluster $Cluster -Name $DrsGroup
      }
      if (-not $DrsGroup) {
        Write-Error "The DrsGroup $DrsGroupName was not found on cluster $($Cluster.name)."
      }
      else { 
        if ($DrsGroup.GetType().Name -ne "ClusterVmGroup") {
          Write-Error "The DrsGroup $DrsGroupName on cluster $($Cluster.Name) doesn't have the required type ClusterVmGroup."
        }
        else {
          $VM = $Cluster | Get-VM -Name $VM
          If ($VM) {
            $spec = New-Object VMware.Vim.ClusterConfigSpecEx
            $spec.groupSpec = New-Object VMware.Vim.ClusterGroupSpec[] (1)
            $spec.groupSpec[0] = New-Object VMware.Vim.ClusterGroupSpec
            $spec.groupSpec[0].operation = "edit"
            $spec.groupSpec[0].info = $DrsGroup
            $spec.groupSpec[0].info.vm += $VM.ExtensionData.MoRef

            $Cluster.ExtensionData.ReconfigureComputeResource_Task($spec, $true)
          }
        }
      }
    }
  }
}

Regards, Robert

I changed the logic of the error handling in the Add-VMToDrsGroup function.

Message was edited by: RvdNieuwendijk

Blog: https://rvdnieuwendijk.com/ | Twitter: @rvdnieuwendijk | Author of: https://www.packtpub.com/virtualization-and-cloud/learning-powercli-second-edition

View solution in original post

13 Replies
RvdNieuwendijk
Leadership
Leadership

You can add virtual machines to a DRS affinity rule with the Set-DrsRule cmdlet. Take a look at example 1 of the Set-DrsRule help:

C:\PS>$vm = Get-VM DrsRuleVM1*

Set-DrsRule -Rule $affinityRule -VM $vm -Enabled $true;


Updates the list of virtual machines that might be referenced by the DRS rule stored in the $affinityRule  variable and enables the rule.



Regards, Robert

Blog: https://rvdnieuwendijk.com/ | Twitter: @rvdnieuwendijk | Author of: https://www.packtpub.com/virtualization-and-cloud/learning-powercli-second-edition
0 Kudos
broedi
Contributor
Contributor

Hi Robert,

thanks for the reply but it doesn't solve my problem.

I use the "Virtual Machnes to Hosts" rule-type (not the affinity rule/anti-affinity rule).

Regards,

Willibald

0 Kudos
RvdNieuwendijk
Leadership
Leadership

Hi Willibald,

take a look at http://communities.vmware.com/message/1666605#1666605. The script presented there by Luc creates a "Run VMs on Hosts" type DRS Rule.

Regards, Robert

Blog: https://rvdnieuwendijk.com/ | Twitter: @rvdnieuwendijk | Author of: https://www.packtpub.com/virtualization-and-cloud/learning-powercli-second-edition
0 Kudos
broedi
Contributor
Contributor

Hi again,

I check that already but the script creates a new DRS-Rule (it's the same rule-type which I use).

What i like to do is to add additional VMs to that rule.

Regards,

Willibald

0 Kudos
RvdNieuwendijk
Leadership
Leadership

Hi Willibald,

I did some investigation in the VMware vSphere SDK and made two functions Get-DrsGroup and Add-VmToDrsGroup to add one or more virtual machines to a ClusterVmGroup. Some examples of how to use these function are in the code. If you have added these functions to your PowerCLI session, you can use Get-Help to get information about these functions. And also to get the examples. E.g. Get-Help Add-VmToDrsGroup -Full.

Function Get-DrsGroup {
<#
.SYNOPSIS
Retrieves DRS groups from a cluster.

.DESCRIPTION
Retrieves DRS groups from a cluster.

.PARAMETER Cluster
Specify the cluster for which you want to retrieve the DRS groups

.PARAMETER Name
Specify the name of the DRS group you want to retrieve.

.EXAMPLE
Get-DrsGroup -Cluster $Cluster -Name "VMs DRS Group"
Retrieves the DRS group "Vms DRS Group" from cluster $Cluster.

.EXAMPLE
Get-Cluster | Get-DrsGroup
Retrieves all the DRS groups for all clusters.

.INPUTS
ClusterImpl

.OUTPUTS
ClusterVmGroup
ClusterHostGroup

.COMPONENT
VMware vSphere PowerCLI
#>

  param([parameter(Mandatory=$true, ValueFromPipeline=$true)]$Cluster,
        [string] $Name="*")

  process {
    $Cluster = Get-Cluster -Name $Cluster
    if($Cluster) {
      $Cluster.ExtensionData.ConfigurationEx.Group | `
      Where-Object {$_.Name -like $Name}
    }
  }
}
  
Function Add-VMToDrsGroup {
<#
.SYNOPSIS
Adds a virtual machine to a cluster VM DRS group.

.DESCRIPTION
Adds a virtual machine to a cluster VM DRS group.

.PARAMETER Cluster
Specify the cluster for which you want to retrieve the DRS groups

.PARAMETER DrsGroup
Specify the DRS group you want to retrieve.

.PARAMETER VM
Specify the virtual machine you want to add to the DRS Group.

.EXAMPLE
Add-VMToDrsGroup -Cluster $Cluster -DrsGroup "VM DRS Group" -VM $VM
Adds virtual machine $VM to the DRS group "VM DRS Group" of cluster $Cluster.

.EXAMPLE
Get-Cluster MyCluster | Get-VM "A*" | Add-VMToDrsGroup -Cluster MyCluster -DrsGroup $DrsGroup
Adds all virtual machines with a name starting with "A" in cluster MyCluster to the DRS group $DrsGroup of cluster MyCluster.

.INPUTS
VirtualMachineImpl

.OUTPUTS
Task

.COMPONENT
VMware vSphere PowerCLI
#>

  param([parameter(Mandatory=$true)] $Cluster,
        [parameter(Mandatory=$true)] $DrsGroup,
        [parameter(Mandatory=$true, ValueFromPipeline=$true)] $VM)
        
  begin {
    $Cluster = Get-Cluster -Name $Cluster
  }
  
  process {
    if ($Cluster) {
      if ($DrsGroup.GetType().Name -eq "string") {
        $DrsGroupName = $DrsGroup
        $DrsGroup = Get-DrsGroup -Cluster $Cluster -Name $DrsGroup
      }
      if (-not $DrsGroup) {
        Write-Error "The DrsGroup $DrsGroupName was not found on cluster $($Cluster.name)."
      }
      else { 
        if ($DrsGroup.GetType().Name -ne "ClusterVmGroup") {
          Write-Error "The DrsGroup $DrsGroupName on cluster $($Cluster.Name) doesn't have the required type ClusterVmGroup."
        }
        else {
          $VM = $Cluster | Get-VM -Name $VM
          If ($VM) {
            $spec = New-Object VMware.Vim.ClusterConfigSpecEx
            $spec.groupSpec = New-Object VMware.Vim.ClusterGroupSpec[] (1)
            $spec.groupSpec[0] = New-Object VMware.Vim.ClusterGroupSpec
            $spec.groupSpec[0].operation = "edit"
            $spec.groupSpec[0].info = $DrsGroup
            $spec.groupSpec[0].info.vm += $VM.ExtensionData.MoRef

            $Cluster.ExtensionData.ReconfigureComputeResource_Task($spec, $true)
          }
        }
      }
    }
  }
}

Regards, Robert

I changed the logic of the error handling in the Add-VMToDrsGroup function.

Message was edited by: RvdNieuwendijk

Blog: https://rvdnieuwendijk.com/ | Twitter: @rvdnieuwendijk | Author of: https://www.packtpub.com/virtualization-and-cloud/learning-powercli-second-edition
broedi
Contributor
Contributor

Hi Robert,

thanks a lot. Thats exactly what I looked for 🙂

Best regards,

Willibald

0 Kudos
Zsoldier
Expert
Expert

Nice functions Robert.  These or some variant of these should be added as cmdlets to the next version of PowerCLI.

I would think Get-DRSGroup is good as is, but would like to see something more along the lines of Set-DRSGroup, Add-DRSGroup, Remove-DRSGroup as more generalized and flexible cmdlets than Add-VMToDRSGroup.

Chris Nakagaki (中垣浩一)
Blog: https://tech.zsoldier.com
Twitter: @zsoldier
0 Kudos
GreyhoundHH
Enthusiast
Enthusiast

I had to dig out this older thread 😃

I'm testing the posted script to automatically place certain VMs in specific DRS-Groups. This qorks quite well so far, but one thing bothers me. A task is created for EVERY VM to add it to the desired DRS-Group even if it's already in there. How can the function be modified so that tasks will only be created for VMs which are not yet in DRS-Group.

0 Kudos
GreyhoundHH
Enthusiast
Enthusiast

Anyone having any idea?

0 Kudos
OsburnM
Hot Shot
Hot Shot

Greetings.  I know this is a bit old so hopefully someone can help.

I've been asked to generate a regular report that contains the ESXi Hosts's name of each host that is a member of a particular DRS group.

I believe the function above 'Get-DRSGroup' just about get's me there; however, it doesn't spit the information out in a friendly way, nor with the Host's actual name.

Any help?

0 Kudos
chikini
Contributor
Contributor

hi,

excellent! thank a lot!

0 Kudos
sastre
Enthusiast
Enthusiast

I'm amazed that it's 2015 and this is still not possible within the latest version of PowerCLI!

0 Kudos
LucD
Leadership
Leadership

The DRSRule module does that for you, see DRSRule – a DRS rules and groups module


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

0 Kudos