1 2 Previous Next 22 Replies Latest reply on Aug 12, 2014 7:51 AM by steveschofield

    Script to automate DRS-Groups Manger affinity

    radio_müsli Novice

      Hello

       

      I'm trying to automate affinity rules for drs groups manger. The idea is to let certain VMs run on

      assigned esx hosts (Type "Run VMs on Hosts" / "Should run on hosts in group").

       

      Background: We've esx hosts in two datacenters interconnected with 10Gig and a netapp metrocluster on each site hosting nfs exports. I have created two groups of type "Host DRS Groups" (esx hosts in datacenter a go into one, hosts in datacenter b go into the other) plus two groups of type "Virtual Machine DRS Groups" (VMs hosted on nfs export a go into one while VMs hosted on nfs export b go into the other). This way we can prevent nfs/iscsi traffic to run across datacenters.

       

      Creating the rules manually in a small cluster does work. However with dozens of VMs in other clusters there must be a way to automate the task and have it run regualary. I would let powercli generate a list of VMs according to nfs export (location of .vmdk is either on site a or site b) then import this into the relevant Virtual Machine DRS Group.

       

      Using get-drsrule -Cluster "cluster" | Export-CliXml does not show details for HOST DRS Groups or Virtual Machine DRS Groups. Is it possible to do this at all? I recon using set-drsrule would let me import the rules.

       

      Any help / ideas is appreceated!

       

      Regards

      Sascha

        • 1. Re: Script to automate DRS-Groups Manger affinity
          LucD Guru
          vExpertUser ModeratorsCommunity Warriors

          The current DrsRule cmdlets do not, afaik, allow you to work with DRS groups.

          As an alternative you can use the ReconfigureComputeResource method that is available.

           

          The script would look something like this

           

          $clusterName = "MyCluster"
          $cluster = Get-Cluster -Name $clusterName

          $spec = New-Object VMware.Vim.ClusterConfigSpecEx $groupVM = New-Object VMware.Vim.ClusterGroupSpec
          $groupVM.operation = "add"
          $groupVM
          .Info = New-Object VMware.Vim.ClusterVmGroup
          $groupVM.Info.Name = "Grouped VM"

          Get-VM
          -Name MyVM1* | %{     $groupVM.Info.VM += $_.Extensiondata.MoRef } $spec.GroupSpec += $groupVM
          $groupESX
          = New-Object VMware.Vim.ClusterGroupSpec
          $groupESX
          .operation = "add"
          $groupESX.Info = New-Object VMware.Vim.ClusterHostGroup
          $groupESX.Info.Name = "Grouped Host"

          Get-VMHost
          -Name MyHost1* | %{     $groupESX.Info.Host += $_.Extensiondata.MoRef } $spec.GroupSpec += $groupESX
          $rule
          = New-Object VMware.Vim.ClusterRuleSpec
          $rule
          .operation = "add"
          $rule.info = New-Object VMware.Vim.ClusterVmHostRuleInfo
          $rule.info.enabled = $true
          $rule.info.name = "Test DRS group rule"
          $rule.info.mandatory = $true
          $rule
          .info.vmGroupName = "Grouped VM"
          $rule
          .info.affineHostGroupName = "Group Host"
          $spec.RulesSpec += $rule
          $cluster.ExtensionData.ReconfigureComputeResource($spec,$true)

          The script first creates 2 DRS groups. One with the VMs and one with the ESX(i) servers.

          In the example it takes all guests whose name starts with "MyVM1" for one group and all hosts whose name starts with "MyHost1" for the other group.

          These 2 selections will of course have to be changed for your setup. Let me know what selection rules you want to implement for the VMs and the hosts and I can update the script.

           

          Then the script creates a rule. Notice that the rule specifies $true for the 'mandatory' property.

          This means that a VM will not be powered on if its host placement doesn't correspond with the rule.

           

          The 2nd parameter on the ReconfigureComputeResource method allows you to specify if the changes defined in the $spec are incremental or not.

          If this is not $true all your cluster settings, except for the groups and the rule will be removed. So watch out!

          • 2. Re: Script to automate DRS-Groups Manger affinity
            radio_müsli Novice

            Awesome! Just what I was looking for

            • 3. Re: Script to automate DRS-Groups Manger affinity
              broedi Novice

              Hi,

               

              great script! :-)

               

              Is it possible to create an example how to add additional VMs to that existing Group "Grouped VM"?

               

              Thanks!

              • 4. Re: Script to automate DRS-Groups Manger affinity
                GotMoo Lurker

                I was also looking for a script to modify/update Virtual Machine DRS Groups in the DRS Group Manager.

                 

                I modified the script above to create this:

                 

                 

                $vCenterServer = "vCenter.Example.com"
                #authenticating and Connecting to the VC
                
                $CurrentUserName = [Security.Principal.WindowsIdentity]::getcurrent().name
                $cred = Get-Credential $CurrentUserName
                Write-Output "Connecting to vCenter. Please stand by..."
                Connect-VIServer -Server $vCenterServer -Credential $Cred
                
                
                #Function for updating the Resource VM Groups
                function updateDrsVmGroup ($clusterName,$resourcePoolName,$groupVMName){
                    $cluster = Get-Cluster -Name $clusterName
                    $spec = New-Object VMware.Vim.ClusterConfigSpecEx
                    $groupVM = New-Object VMware.Vim.ClusterGroupSpec 
                    #Operation edit will replace the contents of the GroupVMName with the new contents seleced below.
                    $groupVM.operation = "edit" 
                
                    $groupVM.Info = New-Object VMware.Vim.ClusterVmGroup
                    $groupVM.Info.Name = $groupVMName 
                
                # Perform your VM selection here. I use resource pools per cluster to identify group members, 
                # but you could use any method to select your VM's. 
                    get-cluster $clusterName | Get-ResourcePool $resourcePoolName | get-vm | %{
                        $groupVM.Info.VM += $_.Extensiondata.MoRef
                    }
                    $spec.GroupSpec += $groupVM
                
                    #Apply the settings to the cluster
                    $cluster.ExtensionData.ReconfigureComputeResource($spec,$true)
                }
                
                # Calling the function. I've found the group names to be case sensitive, so watch for that.
                #updateDrsVmGroup ("ClusterName") ("ResourcePool Name") ("DRS VM Groupname")
                updateDrsVmGroup ("Cluster_PROD") ("Group A") ("Group A VMs (Odd)")
                updateDrsVmGroup ("Cluster_PROD") ("Group B") ("Group B VMs (Even)")
                updateDrsVmGroup ("Cluster_STAGE") ("Group A") ("Group A VMs (Odd)")
                updateDrsVmGroup ("Cluster_STAGE") ("Group B") ("Group B VMs (Even)")
                
                
                Disconnect-VIServer -Confirm:$False
                

                 

                This script allows me to manage guest to host affinity across clusters on the same hardware (blade chassis) based on resource pool membership.  The VM group contents will be overwritten by whatever the script finds in the resource pools matching the name.

                • 5. Re: Script to automate DRS-Groups Manger affinity
                  JustinL3 Novice

                  LucD and GotMoo,

                   

                  Thanks for posting your scripts to create and modify DRS Groups.  Work great and give me peace of mind that I'm not forgetting to seperate any of my clustered VM nodes.

                   

                  J

                  • 6. Re: Script to automate DRS-Groups Manger affinity
                    rosarre Lurker

                    Hello LucD

                     

                    Do you have a similar script the will output the contents of a DRS group as well as the Virtual Machine DRS groups and the Host DRS groups

                     

                    Thanks

                     

                    BobR

                    • 7. Re: Script to automate DRS-Groups Manger affinity
                      EsVau Lurker

                      Hi,

                      I'm want to set the Group affinity based on a cutom attribute that we are using. I tried it using get-annotation but it's not really working.

                       

                      Get-Cluster $clusterName | Get-VM | Get-Annotation | where {$_.value -eq $Datacenter} | Select-Object AnnotatedEntity

                      With that I get the needed output, but placed in the whole script it's doesn't work.

                       

                      Somebody have any Ideas?

                       

                      THX, Stefan

                       

                       

                      • 8. Re: Script to automate DRS-Groups Manger affinity
                        LucD Guru
                        Community WarriorsvExpertUser Moderators

                        Could you perhaps explain in which context in your script you want to use the AnnotatedEntity property ?

                        • 9. Re: Script to automate DRS-Groups Manger affinity
                          EsVau Lurker

                          Of cource, sorry.

                           

                          I want to set the affinity of my VM's to DR's groups based on a custom attribute we set (Datacenter). It should work like the script of GotMoo, but instead of based on RessourcePools it should be based on the entry of the Datacenter-Attribute.

                           

                          "Get-Cluster $clusterName | Get-VM | Get-Annotation | where {$_.value -eq $Datacenter} | Select-Object AnnotatedEntity" gives me the names of the VM's as output. Similar to "get-cluster $clusterName | Get-ResourcePool $resourcePoolName | get-vm" in the script of GotMoo.

                           

                          I just started using PS, so maybe it's the total different way. Please don't gve to much attention on what I've done, if there is a better way I'm happy for tips.

                          • 10. Re: Script to automate DRS-Groups Manger affinity
                            LucD Guru
                            User ModeratorsvExpertCommunity Warriors

                            Try replacing that part of the script with this

                             

                                Get-Cluster $clusterName | Get-VM | 
                                where {Get-Annotation -Entity $_ | where {$_.Value -eq $Datacenter}} | %{
                                    $groupVM.Info.VM += $_.Extensiondata.MoRef
                                }
                            }

                             

                            This will get all the VMs in the cluster and then filter, with a Where-clause, the ones that have the content of the $Datacenter variable in one of their custom attributes.

                            • 11. Re: Script to automate DRS-Groups Manger affinity
                              EsVau Lurker

                              Works perfect!!!

                              THX very much!!!

                              • 12. Re: Script to automate DRS-Groups Manger affinity
                                Martin Gustafsson Hot Shot

                                Hi fellas,

                                 

                                Looking for a way to use Datastore Clusters in the same way you use Resource pools/annotations.

                                Is there a way to select the VMs stored on a specific datastore cluster? I find the get-datastorecluster to be very limited.

                                 

                                 

                                Basically what we want to do is to fill our two VM DRS Groups (stretched HA cluster) with the VMs filled in the resource pool named PROD.

                                We have two Datastore Clusters named PROD_SITE_A and PROD_SITE_B.

                                 

                                I can get the output of where all the VM resides, but I don't see a way to implement it into the script.

                                 

                                Get-ResourcePool PROD |Get-VM | Select Name, @{N="Datastore";E={Get-Datastorecluster -VM $_}}

                                Will give a nice output of each VM and what Datastore Cluster its stored on.

                                 

                                 

                                It would be so much easier if you just could get-datastorecluster PROD_SITE_A | get-vm ...

                                 

                                Any suggestions?

                                • 13. Re: Script to automate DRS-Groups Manger affinity
                                  LucD Guru
                                  Community WarriorsvExpertUser Moderators

                                  I agree that the Datastorecluster related cmdlets should be expanded.

                                  Let's hope the next PowerCLI release will bring that.

                                   

                                  In the meantime, you can use this function to retrieve the VMs that are located on a Datastorecluster

                                   

                                  function Get-VMonDsc{
                                    param(
                                    [CmdletBinding()]
                                    [parameter(Position = 0, ValueFromPipeline = $true)]
                                    [string]$Name = "*"  )
                                  
                                    begin{
                                     function Get-StoragePodInternal{
                                       param(
                                       [CmdletBinding()]
                                       [parameter(Mandatory = $true,ValueFromPipeline = $true)]
                                       [VMware.Vim.Folder]$Folder     )
                                  
                                       $Folder.ChildEntity | %{
                                         if($_.Type -eq "StoragePod"){
                                           Get-View -Id $_
                                         }       
                                  elseif($_.Type -eq "Folder"){          Get-View -Id $_ | Get-StoragePodInternal
                                         }      }     }   }     process{     Get-Folder -Name datastore | %{       Get-StoragePodInternal -Folder $_.ExtensionData | where {$_.Name -like $Name} | %{         Get-VIObjectByVIView -MORef $_.ChildEntity | Get-VM
                                        }     }   } }
                                  $vms = Get-VMOnDsc -Name "DSC1"

                                   

                                  The function is based on my vSphere 5 Top 10 – Storage DRS post.

                                  • 14. Re: Script to automate DRS-Groups Manger affinity
                                    Martin Gustafsson Hot Shot

                                    Thanks alot Luc!

                                     

                                    It works like a charm.

                                    1 2 Previous Next