Luc Dekens and I got together on a new PowerShell module for managing/exporting/importing DRS Rules and Groups. See our posts at http://www.lucd.info/2015/01/22/drsrule-drs-rules-and-groups-module and http://www.vnugglets.com/2015/01/drsrule-new-powershell-module-for-drs.html for all of the juicy details. Going forward, that DRSRule module is the way to go. I am leaving this post intact for posterity. Enjoy!
End of update - 22 Jan 2015
We, like many, had the need for a way to backup our DRS rules. Searches turned up many pages, all of which had the same basic recipe: use the Get-DrsRule to grab the rules, get a few properties, and export to CSV.
The problem: Addressing the task getting all of the pertinent info for rules of type ClusterVmHostRuleInfo, or, "VM-to-Host" rules. Rules of this type do not have the VM IDs in a property of the rule, but rather have the VMGroupName and HostGroupNames properties. From these properties, and the .NET view object of the given cluster, one can retrieve the VMs' and hosts' info.
So, we did a little work, and wrote the following to, for all DRS rule types, get the information that would be required if one wanted to recreate the rules:
## Script function: Gather/export DRS rule info, including VMGroup and HostGroup members ## Author: vNugglets.com ## file to which to write the DRS rules' info $strOutputFilespec = "e:\someFolder\DRSrules_export.csv" ## get cluster .NET view objects, which hold the info about the DRS rules Get-View -ViewType ClusterComputeResource -Property Name, ConfigurationEx | %{ ## if the cluster has any DRS rules if ($_.ConfigurationEx.Rule -ne $null) { $viewCurrClus = $_ $viewCurrClus.ConfigurationEx.Rule | %{ $oRuleInfo = New-Object -Type PSObject -Property @{ ClusterName = $viewCurrClus.Name RuleName = $_.Name RuleType = $_.GetType().Name bRuleEnabled = $_.Enabled bMandatory = $_.Mandatory } ## end new-object ## add members to the output object, to be populated in a bit "bKeepTogether,VMNames,VMGroupName,VMGroupMembers,AffineHostGrpName,AffineHostGrpMembers,AntiAffineHostGrpName,AntiAffineHostGrpMembers".Split(",") | %{Add-Member -InputObject $oRuleInfo -MemberType NoteProperty -Name $_ -Value $null} ## switch statement based on the object type of the .NET view object switch ($_){ ## if it is a ClusterVmHostRuleInfo rule, get the VM info from the cluster View object # a ClusterVmHostRuleInfo item "identifies virtual machines and host groups that determine virtual machine placement" {$_ -is [VMware.Vim.ClusterVmHostRuleInfo]} { $oRuleInfo.VMGroupName = $_.VmGroupName ## get the VM group members' names $oRuleInfo.VMGroupMembers = (Get-View -Property Name -Id ($viewCurrClus.ConfigurationEx.Group | ?{($_ -is [VMware.Vim.ClusterVmGroup]) -and ($_.Name -eq $oRuleInfo.VMGroupName)}).Vm | %{$_.Name}) -join "," $oRuleInfo.AffineHostGrpName = $_.AffineHostGroupName ## get affine hosts' names $oRuleInfo.AffineHostGrpMembers = if ($_.AffineHostGroupName -ne $null) {(Get-View -Property Name -Id ($viewCurrClus.ConfigurationEx.Group | ?{($_ -is [VMware.Vim.ClusterHostGroup]) -and ($_.Name -eq $oRuleInfo.AffineHostGrpName)}).Host | %{$_.Name}) -join ","} $oRuleInfo.AntiAffineHostGrpName = $_.AntiAffineHostGroupName ## get anti-affine hosts' names $oRuleInfo.AntiAffineHostGrpMembers = if ($_.AntiAffineHostGroupName -ne $null) {(Get-View -Property Name -Id ($viewCurrClus.ConfigurationEx.Group | ?{($_ -is [VMware.Vim.ClusterHostGroup]) -and ($_.Name -eq $oRuleInfo.AntiAffineHostGrpName)}).Host | %{$_.Name}) -join ","} break; } ## end block ## if ClusterAffinityRuleSpec (or AntiAffinity), get the VM names (using Get-View) {($_ -is [VMware.Vim.ClusterAffinityRuleSpec]) -or ($_ -is [VMware.Vim.ClusterAntiAffinityRuleSpec])} { $oRuleInfo.VMNames = if ($_.Vm.Count -gt 0) {(Get-View -Property Name -Id $_.Vm | %{$_.Name}) -join ","} } ## end block {$_ -is [VMware.Vim.ClusterAffinityRuleSpec]} { $oRuleInfo.bKeepTogether = $true } ## end block {$_ -is [VMware.Vim.ClusterAntiAffinityRuleSpec]} { $oRuleInfo.bKeepTogether = $false } ## end block default {"none of the above"} } ## end switch $oRuleInfo } ## end foreach-object } ## end if } | Export-Csv -NoTypeInformation $strOutputFilespec
This bit of code, using the Get-View cmdlet for max speed and min memory footprint, starts off by getting a couple of select properties for all clusters. If the cluster has any DRS rules defined, then the code, for each rule:
- creates a new PSObject to hold the pertinent info about the rule
- includes basic rule info, the rule type, and info about the objects involved with the rule, including the VM group names/members and the host group names/members (for both Affine- and AntiAffine host groups)
- returns the object
- exports all of the gathered info to CSV for later consumption
Arnim van Lieshout wrote a good post with more information about DRS rules themselves at Managing VMware DRS rules using PowerCLI, and included a few functions for creating VMGroups ("Virtual Machines DRS Groups" in the vSphere client) and HostGroups ("Host DRS Groups"), and for creating new VM-to-Host rules. We will likely be using said functions for our "recreate the DRS rules/groups" work.
This is great! Thanks.
ReplyDeleteTom
Thanks for the feedback, Tom. One day we will get around to posting the complementary Restore/Import kin article...
DeleteThis Script is fast and gets the job done!
DeletePlease post the Restore script to match ASAP!
Nick
Hi there!
ReplyDeleteTotally awesome script! Thank you for your good work! Do you plan on making a restore-script anytime soon? :-)
Excellent Script. Thank you. It does throw some minor (ignoreable) errors for those clusters that it cannot find Host/VM groups for. i.e. that only have vm anti or affinity rules but not groups.
ReplyDeleteIs that the cause of the following error?
DeleteGet-View : Cannot validate argument on parameter 'Id'. The argument is null or empty. Provide an argument that is not null or empty, and then try the
command again.
At line:30 char:78
+ $oRuleInfo.VMGroupMembers = (Get-View -Property Name -Id ($v ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Get-View], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,VMware.VimAutomation.ViCore.Cmdlets.Commands.DotNetInterop.GetVIView
I received this same error. It was because one of my DRS groups didn't actually have any members. I was able to ignore the message.
DeleteHi all ,I got same problem and did you fix this issue ?? if fix this issue can you share me the way to me?my email address is owengo@qq.com
DeleteHello, Guocai Liang-
DeleteThe DRSRule PowerShell module supercedes the code in this post. Luc Dekens and I wrote said PowerShell module for managing/exporting/importing DRS Rules and Groups. See our posts at http://www.lucd.info/2015/01/22/drsrule-drs-rules-and-groups-module and http://www.vnugglets.com/2015/01/drsrule-new-powershell-module-for-drs.html.
And, if you find issues with the module, or have some feature requests, or want to contribute, check out the module at GitHub at https://github.com/PowerCLIGoodies/DRSRule.
Cheers! Matt
A downfall to this script I noticed is that it won't export any groups that are not used. I have a few DRS groups defined but they aren't currently used in any rules.
ReplyDeleteTo get all group membership I was able to use the Get-DrsGroup function located here https://communities.vmware.com/message/1699823#1699823
Deleteand run these commands...
foreach ($group in (Get-DrsGroup -Cluster "ClusterName")) {
$group.Name
foreach ($obj in $group.vm) {
(get-view -id $obj).name
}
foreach ($obj in $group.host) {
(get-view -id $obj).name
}
Write-Output ""
}
Any update on the import script? I'm looking to migrate a datacenter/cluster to a new vcenter and the import would greatly help.
ReplyDeleteThanks!
Hello, Anonymous-
DeleteIf you didn't see, Luc Dekens and I wrote a PowerShell module to handle imports and much more -- managing/exporting/importing DRS Rules and Groups. See our posts at http://www.lucd.info/2015/01/22/drsrule-drs-rules-and-groups-module and http://www.vnugglets.com/2015/01/drsrule-new-powershell-module-for-drs.html. Enjoy!
Great script!
ReplyDeleteGood job! Could you please tell me how to import the rule from exported csv files?
ReplyDeleteMy email is owengo@qq.com.Thanks for your help.
Hello, Owengo@qq-
DeleteThanks! As for importing from exports: the way to go now would to be to use the DRSRule PowerShell module that supercedes the code in this post. Luc Dekens and I wrote said PowerShell module to handle imports and much more -- managing/exporting/importing DRS Rules and Groups. See our posts at http://www.lucd.info/2015/01/22/drsrule-drs-rules-and-groups-module and http://www.vnugglets.com/2015/01/drsrule-new-powershell-module-for-drs.html.
And, particularly for your use cases, see the Export-DrsRule and Import-DrsRule cmdlets in the module. Enjoy!
Great looking script, is this still valid in 2020? Tried to use it on vCenter 6.7u3 and received this error:
ReplyDelete"Get-View : Cannot validate argument on parameter 'Id'. The argument is null or empty. Provide an argument that is not null or empty, and then try the command again."
Desktop\DRSBackups-Working.ps1:31 char:78
+ ... ty Name -Id ($viewCurrClus.ConfigurationEx.Group | ?{($_ -is [VMware. ...
Line 31 is:
$oRuleInfo.VMGroupMembers = (Get-View -Property Name -Id ($viewCurrClus.ConfigurationEx.Group | ?{($_ -is [VMware.Vim.ClusterVmGroup]) -and ($_.Name -eq $oRuleInfo.VMGroupName)}).Vm | %{$_.Name}) -join ","
Greetings, Mathiau-
DeleteThanks! Yes, while this beauty should still work a dream, it is deprecated in favor of the full-on PowerShell module for such things: the "DRSRule" PowerShell module. Luc Dekens and I wrote said PowerShell module to handle imports and much more -- managing/exporting/importing DRS Rules and Groups. See our posts at http://www.lucd.info/2015/01/22/drsrule-drs-rules-and-groups-module and http://www.vnugglets.com/2015/01/drsrule-new-powershell-module-for-drs.html.
And, particularly for your use cases, see the Export-DrsRule and Import-DrsRule cmdlets in the module. Enjoy!