One of the nice vSphere features is the ability to define DRS rules.
The feature allows a vSphere administrator to control the placement of virtual machines in a vSphere cluster. There are the VM to VM affinity and anti-affinity rules, and the newer VM to VMHost rules. With the VM to VMHost rules, vSphere introduced the concept of VM and VMHost groups, and the ability to have rules that are a requirement (‘shall’) or a preference (‘should’).
In a recent VMTN PowerCLI community thread a PowerCLI user had a query about exporting and importing DRS rules and groups. At that point Matt Boren and myself developed the idea to provide a PowerShell module. The PowerShell module, which we named DRSRule, provides all the functions we deemed useful for working with DRS rules and groups. And yes, the module includes an export and an import cmdlet !
Matt Boren, famous for the high quality posts on his vNugglets blog, and myself, started working on the module, and after some late evenings and long weekends, we now have a first version we want to make public.
There are already many blogposts on the subject of DRS rules and groups. Including some excellent PowerCLI posts. The first one that springs to mind is Arnim‘s excellent Managing VMware DRS rules using PowerCLI.
And don’t forget to read Matt’s post on the DRSRule module as well.
To get you on your way with the DRSRule module, Matt and myself compiled the following introductory text.
Why the DRSRule module?
The core PowerCLI from VMware allows for many of the DRS rule operations that one might want to perform. There have been questions over the years in the VMware Communities PowerCLI forum about how to export DRS rules and groups, and, on how to then import such items.
While there are several posts on the web about how to get/export such things, importing/recreating DRS rules/groups from such exported data has not received much focus. This was the spark for this DRSRule module: to allow for easy export/import of such rules/groups. As part of making a module to handle these actions, other cmdlets were born, like the Get-/New-/Remove-/Set-* cmdlet sets for DRS VM groups and VMHost groups, along with sets for DRS VM to VM rules and VM to VMHost rules.
How to use the DRSRule module?
The DRSRule module comes with an about_DRSRule.
Once the module is installed, use that help topic to get a general introduction to the use of the DRSRule module:
1 |
Get-Help about_DRSRule |
How to get the DRSRule module ?
The source for this PowerShell module is hosted on GitHub.com.
The repository is managed by the GitHub organization PowerCLIGoodies, and in there is the DRSRule repository itself.
There are a couple of ways to get the module, and use it in your PowerShell session:
Automated
Via a script
Use a PowerShell script to perform the download and the extract.
The script is included in the repository as file DownloadLatest.ps1.
Via PsGet
If you have the PsGet module loaded in your PowerShell session, then installing this DRSRule module is as simple as updating PsGet and then installing DRSRule:
1 2 |
Update-Module -Verbose -Module PsGet Install-Module DRSRule |
Manual
Grab the latest version from the GitHub repository.
Extract the content to a suitable folder.
You can go for the Modules folder linked to the Windows account you are using. To find this path, run:
1 |
Join-Path ${env:\userprofile} "Documents\WindowsPowerShell\Modules") |
Or you can select any other folder.
Either way you will end up with a folder named [pathToModule]\DRSRule, in which the PowerShell files for the DRSRule module reside.
Then, load the DRSRule module into your session.
If you selected one of the folders in $env:PSModulePath (your PSModule path), you can do this with
1 |
Import-Module DRSRule |
If you picked another folder, you should use the full path to the folder that contains the module’s files, like:
1 |
Import-Module [PathToModule]\DRSRule |
Please also read the note below about using Unblock-File, since this module is not Authenticode signed.
Note on Unblock-File
Since there is no Authenticode certificate supplied for this module, and, assuming that one’s PowerShell ExecutionPolicy is at least RemoteSigned, below is a quick/easy way to unblock files. But, this should only be done when you trust the code in the files that you are unblocking — inspecting the files is for your own good.
1 |
Get-ChildItem [pathToModules]\DRSRule | Unblock-File |
The DRSRule module was set up as community resource, so we are hoping to see your comments, suggestions and code.
Enjoy !
Momox
I just wanted to thank you for the module. You make my job easier ^^
I haven’t seen you during last vmexplore Barcelona… will you be present this year?
regards,
LucD
Thank you, much appreciated.
I retired 2 years ago, my presenting days are over.
I have a slew of new hobbies to dive into 😉
Subhash
I am looking for a script to check all VMs in Vcenter are part of a DRS group,if yes report with DRS group name, running esxi host, VM’s path etc..
LucD
Hi,
What do you already have and which problems do you encounter?
Also not that the recent PowerCLI releases do have a set of DRS related cmdlets.
Nits
Hi LucD,
I’m working with a script to import DRS affinity rules and I’m running powercli 11.3 and the parameter -KeepTogether cannot be bound as it is NULL. Under is the script I’m using and was wondering if -KeepTogether parameter is deprecated.
$ClusterForMigration = Import-Csv .\ClusterForMigration_RDCNP.csv
$ClusterName = $ClusterForMigration.Sourcecluster
$file = “C:\Users\A107847\Desktop\scripts\DRS-rules\RDCNAP01_drsrules_RDCNP.txt”
$rules = Get-content $file
foreach ($rule in $rules)
{
$ruleArr = $rule.Split(“,”)
if($ruleArr[2] -eq “True”){$rEnabled = $true} else {$rEnabled = $false}
if($ruleArr[3] -eq “True”){$rTogether = $true} else {$rTogether = $false}
get-cluster $ruleArr[0] | New-DrsRule -Name $ruleArr[1] -Enabled $rEnabled -KeepTogether $rTogehter -VM (Get-VM -Name ($ruleArr[4..($ruleArr.Count – 1)]))
}
ERROR Im getting:
New-DrsRule : Cannot bind argument to parameter ‘KeepTogether’ because it is null.
At C:\Users\XXXXXX\Desktop\drs_rules_import.ps1:19 char:91
+ … -Name $ruleArr[1] -Enabled $rEnabled -KeepTogether $rTogehter -VM (Ge …
+ ~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [New-DrsRule], ParameterBindingException
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,VMware.VimAutomation.ViCore.Cmdlets.Comma
nds.NewDrsRule
LucD
I think you might have a typo in $rTogether
Get-Cluster $ruleArr[0] | New-DrsRule -Name $ruleArr[1] -Enabled $rEnabled -KeepTogether $rTogether -VM (Get-VM -Name ($ruleArr[4..($ruleArr.Count - 1)]))
Nits
That was dumb on my part. Thanks for the correction LucD.
LucD
No problem, happens to the best of us 🙂
Zak
Getting 404 on the download
LucD
Which link from the post are you using?
Btw, the module is also available on the PowerShell Gallery.
Install-Module -Name DrsRule
Nico
Hey there,
Does anyone was able to make this work on powershell 6 on linux appliance ?
I wrote many scripts when I was on 6.0 and now trying to import them on 6.7 …
Thanks for your help guys.
LucD
Hi Nico,
What problems did you encounter?
Nico
Hey Luc,
I’m using the module on windows server so far against a VC 6.0.
Since I’m migrating to 6.7, I’d like to make it work on Linux appliance.
I’m running powershell v6.0.2 on CentOS Linux release 7.2.1511 (Core).
It’s not working anymore.
I use to have the module in this windows path C:\Users\MY_USER\Documents\WindowsPowerShell\Modules\DRSRule
Thank you.
Best,
LucD
Hi Nico,
I’ll have a look
Nico
Hey Luc,
Further investigation from my side:
I have DRSRule module in this path >
PS> ls -ltr /opt/microsoft/powershell/6.0.2/Modules/DRSRule/
total 456
-rw-r–r– 1 root root 2241 Jul 8 18:36 todo.md
-rw-r–r– 1 root root 1729 Jul 8 18:36 README.md
-rw-r–r– 1 root root 1095 Jul 8 18:36 MITLicense.txt
-rw-r–r– 1 root root 1690 Jul 8 18:36 DRSRuleUtil.psm1
-rw-r–r– 1 root root 2651 Jul 8 18:36 DRSRuleUtil.psd1
-rw-r–r– 1 root root 75393 Jul 8 18:36 DRSRule.psm1
-rw-r–r– 1 root root 4178 Jul 8 18:36 DRSRule.psd1
-rw-r–r– 1 root root 4286 Jul 8 18:36 DRSRule.init.ps1
-rw-r–r– 1 root root 185434 Jul 8 18:36 DRSRule.Help.xml
-rw-r–r– 1 root root 128717 Jul 8 18:36 DRSRule.Help.pshproj
-rw-r–r– 1 root root 4126 Jul 8 18:36 DRSRule.format.ps1xml
-rw-r–r– 1 root root 774 Jul 8 18:36 DownloadLatest.ps1
-rw-r–r– 1 root root 21 Jul 8 18:36 contributors.txt
-rw-r–r– 1 root root 3035 Jul 8 18:36 changelog.md
-rw-r–r– 1 root root 7875 Jul 8 18:36 About_DRSRule.help.txt
drwxr-xr-x 2 root root 4096 Oct 9 07:44 testing
—————————————-
I have the following error when I run this command:
PS> Get-DrsVMGroup -Cluster $cluster
Unable to find type [DRSRule.VMGroup].
At /opt/microsoft/powershell/6.0.2/Modules/DRSRule/DRSRule.psm1:55 char:15
+ [OutputType([DRSRule.VMGroup],[VMware.Vim.ClusterVmGroup])]
+ ~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (DRSRule.VMGroup:TypeName) [], RuntimeException
+ FullyQualifiedErrorId : TypeNotFound
—————————————-
And of course, the module is imported as you can see below:
PS> Get-Module
ModuleType Version Name ExportedCommands
———- ——- —- —————-
Script 1.2.1 DRSRule {Export-DrsRule, Get-DrsVMGroup, Get-DrsVMHostGroup, Get-DrsVMToVMHostRule…}
Manifest 3.1.0.0 Microsoft.PowerShell.Management {Add-Content, Clear-Content, Clear-Item, Clear-ItemProperty…}
Manifest 3.1.0.0 Microsoft.PowerShell.Utility {Add-Member, Add-Type, Clear-Variable, Compare-Object…}
Script 1.2 PSReadLine {Get-PSReadlineKeyHandler, Get-PSReadlineOption, Remove-PSReadlineKeyHandler, Set-PSReadlineKeyHandler…}
Script 6.7.0.8… VMware.Vim
Script 10.1.0…. VMware.VimAutomation.Cis.Core {Connect-CisServer, Disconnect-CisServer, Get-CisService}
Script 10.1.0…. VMware.VimAutomation.Common
Script 10.1.0…. VMware.VimAutomation.Core {Add-PassthroughDevice, Add-VirtualSwitchPhysicalNetworkAdapter, Add-VMHost, Add-VMHostNtpServer…}
Script 10.1.0…. VMware.VimAutomation.Sdk {Get-InstallPath, Get-PSVersion}
Any idea to make this work on my linux powershell appliance 🙂 ?
Thanks!
MattQ
With the latest version of PowerCLI (6.5.1 build 5377412), vmware.vim.dll moved again. I changed the top of DRSRule.Init.ps1 to the below to resolve this:
$vacorefolder = (Get-Module vmware.VimAutomation.Core).ModuleBase
if (Test-Path ($vacorefolder + “\VMware.Vim.dll”)) {
$pcliDll = $vacorefolder + “\VMware.Vim.dll”
} elseif ((Get-PowerCLIVersion).Build -ge 4624819){
$pcliDll = “${env:\ProgramFiles(x86)}\VMware\Infrastructure\PowerCLI\Modules\VMware.VimAutomation.Core\VMware.Vim.dll”
}
else{
$pcliDll = “${env:\ProgramFiles(x86)}\VMware\Infrastructure\vSphere PowerCLI\VMware.Vim.dll”
}
LucD
That was fixed in the latest version, DRSRule 1.2.0
Butcha
Hi Luc,
I found that the latest version extracted to a directory named DRSRule_Latest. If the directory name isn’t changed to DRSRule, Powershell refuses to recognize it as a module at all due to the directory name not matching the base name of at least one of its files contained within it.
Steffen Oezcan
Hi Luc,
awesome script which helped me a few times already.
Now I have an environment where there are many virtual datacenters and a certain vSphere cluster name shows up in each of those DCs separately. When I export the rules now, I get the rules from ALL clusters with the specified name.
Any idea how to easily adjust the module to narrow down the scope to a cluster within in a SPECIFIC datacenter? That´d be great.
Thanks, BR and happy holidays
Steffen
LucD
Thanks.
Most of the DrsRule functions accept a Cluster parameter.
Can’t you use that. For example like this
$cluster = Get-Datacenter -Name MyDC | Get-CLuster -Name MyCluster
Get-DrsVMGroup -Cluster $cluster
Or do I miss the question?
cividan
Great module, thanks alot !
LucD
Thanks
RyanD
I am not the greatest scripter but i can manipulate existing scripts. Does anyone happen to have a working script that I could use as a template for exporting and importing these rules?
Peter Bosgraaf
Uber time saver, thanks!!
Dan
Hi Luc –
Would it be possible to specify a vCenter using the import command? I’d like the ability to specify which vCenter to run the import against while connected to multiple vCenters.
Something like:
Import-DrsRule -Path drs.json -Cluster cluster1 -server vCenter1
Thanks
Dan
Gav
When trying to run a import-drsrule I get: Method invocation failed because [System.Management.Automation.PSCustomObject] does not contain a method named
‘GetEnumerator’.
At C:\Users\admin\Documents\WindowsPowerShell\Modules\DRSRule\DRSRule.psm1:1113 char:7
Any ideas?
Natasha
When I run the import it errors. It looks like it’s trying to create every group\rule twice.
PS C:\Users\BLAH> C:\Program Files (x86)\VMware\Infrastructure\vSphere PowerCLI\create DRS Rules.ps1
Name Cluster UserCreated VMHost
—- ——- ———– ——
120H Cluster1… True {Host1, Host1}
Get-Cluster : 3/31/2016 10:31:01 AM Get-Cluster DRS VMHost group named ‘120H’ already exists in cluster ‘Cluster1’
I can use a -ErrorAction SilentlyContinue for the groups. It won’t let the script create multiple copies. But, it does create multiple copies of each of the rules. The .json file only has one entry for each of the groups\rules.
John yang
cool tools~!!
could you please help us to add csv type out files~
SknarfM
Hi Luc,
I’m attempting to use the DRSRule without much success.
I’m receiving the same error as Gram in his post further above.
Here’s the versions I’m running:
Name Value
—- —–
PSVersion 4.0
WSManStackVersion 3.0
SerializationVersion 1.1.0.1
CLRVersion 4.0.30319.34209
BuildVersion 6.3.9600.16406
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0}
PSRemotingProtocolVersion 2.2
I have confirmed that the DRSRule module is in the $PSModulePath. I have also successfully run the Import-Module DRSRule command.
Can you make any suggestions on where I might be going wrong?
thanks
R Holland
Hello.
Just a quick question. Is it possible to use the export-drsrule cmdlet and then import these rules into a seperate cluster using import-drsrule. The new cluster has different named ESXi hosts and also the VM’s have not yet been migrated over.
Thanks for the help.
LucD
If the new environment doesn’t have the same ESXi hosts nor VMs, you would have to edit the export file to adapt the names.
Once done, you should be able to import in the new environment.
Roman
Hello Luc
I asked this yesterday – but my question diappeared…?
Again:
What, if I export some rules und groups from a cluster and migrate this cluster later to another vCenter? Can I import this rules und groups from this previously made export?
Due to a Migration from a cluster to another vCenter, I assume all objects (cluster, Hosts, VMs) get a new ID and therefore the import will fail?
Regards,
Roman
LucD
Sorry about that, don’t know what went wrong.
Probably me being a clumsy web admin 🙂
On your question, the Import-DrsRule function will create the Groups and the Rules. The creation will be based on the Name, not the ID.
So if the ESXi nodes, the cluster and the VMs are present, the importing of the rules should work.
Roman
Hi Luc
Wow! That sounds good!
Many thanks,
Roman
gefleborg
I wonder if this could be usefule as I want to export from my current Windows VCenter 5.5 and import the rules to my new vCSA 6.0 VCenter. What about the VMId? Will it be the same when I disconnect my ESXi’s from old VC an connect them to my new VC?
/Peter
LucD
I’m afraid not, the VM-ID will be different in another vCenter.
But the export does also contain the VM’s name, you can use that to import the rules into the new vCenter.
Roman
You wrote:
“…But the export does also contain the VM’s name, you can use that to import the rules into the new vCenter.”
I don’t understand. How can I import if the VM’s names are correct, but the VM’s IDs wrong? Does a wrong ID have no Impact?
Regards.
LucD
If you use the Import-DrsRule function, the IDs have no impact. The function uses the Name field to recreate Groups and Rules.
Note that the cluster, the ESXi nodes and the VMs need to be there.
Roman
Hello
I can neither Import the module nor unblock the files. We are running PowerCLI 5.8 Release1:
PowerCLI C:\Windows\system32> Get-ExecutionPolicy
RemoteSigned
PowerCLI C:\Windows\system32> Import-Module ‘C:\Program Files\VMware\RCHScripts\DRSRule’
Import-Module : The ‘C:\Program Files\VMware\RCHScripts\DRSRule\DRSRule.psd1’ module cannot be imported because its manifest contains one or more mem
bers that are not valid. The valid manifest members are (‘ModuleToProcess’, ‘NestedModules’, ‘GUID’, ‘Author’, ‘CompanyName’, ‘Copyright’, ‘ModuleVer
sion’, ‘Description’, ‘PowerShellVersion’, ‘PowerShellHostName’, ‘PowerShellHostVersion’, ‘CLRVersion’, ‘DotNetFrameworkVersion’, ‘ProcessorArchitect
ure’, ‘RequiredModules’, ‘TypesToProcess’, ‘FormatsToProcess’, ‘ScriptsToProcess’, ‘PrivateData’, ‘RequiredAssemblies’, ‘ModuleList’, ‘FileList’, ‘Fu
nctionsToExport’, ‘VariablesToExport’, ‘AliasesToExport’, ‘CmdletsToExport’). Remove the members that are not valid (‘RootModule’), then try to impor
t the module again.
At line:1 char:14
+ Import-Module <<< Get-ChildItem ‘C:\Program Files\VMware\RCHScripts\DRSRule’ | Unblock-File
The term ‘Unblock-File’ is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if
a path was included, verify that the path is correct and try again.
At line:1 char:74
+ Get-ChildItem ‘C:\Program Files\VMware\RCHScripts\DRSRule’ | Unblock-File <<<
LucD
Hi Roman,
Sorry to hear that.
Which PowerShell version are you running ?
Do a $PSVersionTable.
Roman
Hi LucD
Sorry for the late answer, but the reason was an old Powershell Version.
Many thanks for that great work!
LucD
Thanks for the feedback
Matt Mauchley
I can export to the json file fine. When i try to import it finishes almost immediately with no output and nothing is imported. Have you seen this before?
Matt
LucD
Hi Matt,
No, can’t say I did.
Could you eventually email (link on my blog page) me the json file ? Make sure to replace sensitive information before you do.
Andre Vechiatto
I have problem when import module
PowerCLI C:\Program Files\VMware\Infrastructure\vSphere PowerCLI> Import-Module C:\Users\n813114\Downloads\DRSRule
Add-Type : (0) : Metadata file ‘\VMware\Infrastructure\vSphere PowerCLI\VMware.Vim.dll’ could not be found
(1) : using VMware.Vim;
At C:\Users\n813114\Downloads\DRSRule\DRSRule.init.ps1:3 char:1
+ Add-Type -ReferencedAssemblies $pcliDll -TypeDefinition @”
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidData: (error CS0006: M…ld not be found:CompilerError) [Add-Type], Exception
+ FullyQualifiedErrorId : SOURCE_CODE_ERROR,Microsoft.PowerShell.Commands.AddTypeCommand
Add-Type : Cannot add type. Compilation errors occurred.
At C:\Users\n813114\Downloads\DRSRule\DRSRule.init.ps1:3 char:1
+ Add-Type -ReferencedAssemblies $pcliDll -TypeDefinition @”
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Add-Type], InvalidOperationException
+ FullyQualifiedErrorId : COMPILER_ERRORS,Microsoft.PowerShell.Commands.AddTypeCommand
LucD
Hi Andre,
It looks as if PowerCLI is not installed.
Can you use any of the PowerCLI cmdlets ?
Wim Dams
I had the same error ..VMware.Vim.dll’ could not be found
The reason is that the default path that includes this dll is changed.
I changed
$pcliDll = “${env:\ProgramFiles(x86)}\VMware\Infrastructure\vSphere PowerCLI\VMware.Vim.dll”
Into
$pcliDll = “${env:\ProgramFiles(x86)}\VMware\Infrastructure\PowerCLI\Modules\VMware.VimAutomation.Core\VMware.Vim.dll”
and now it works again with Powercli 6.5
gram
this is a timer saver. thanks for the work on this module.
i am getting this error trying to export using pcli6 and vc5.1
Get-DrsVMtoVMRule : Unable to find type [DRSRule.VMToVMRule]. Make sure that
the assembly that contains this type is loaded.
At C:\\Temp\\DRSRule-Latest\\DRSRule.psm1:1066 char:9
+ (Get-DrsVMtoVMRule @hshParamsForGetCall),
+ ~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (DRSRule.VMToVMRule:TypeName)
[], RuntimeException
+ FullyQualifiedErrorId : TypeNotFound
LucD
@gram,
A couple of things to check:
Nicolas Piron
Hello LucD!
I have the same problem…
Powershell v4
Import-Module ran fine (I just had to change the $pcliDll variable to point to the correct path as we don’t install PowerCLI on the default path but on D drive…)
The DRSRule module folder is under the default PowerCLI Modules folder…
The module looks great but I would like to use it 😉
Thanks!
Kevin
I had the same issue. Re-installed PowerCLI using the default path C:\Program Files (x86)\VMware\Infrastructure\vSphere PowerCLI and my issue cleared up
Tom
You guys are life savers, busy migrating hosts from one VC to another. You saved me a night of manually re-creating hundreds of rules!
LucD
Thanks Tom, glad it helped you.
KevinK
Hi Luc. Is there any chance you could add the vsphere hostname as a property of get-DrsVMGroup?
Jason Boche
This is cool – Great job!
LucD
Thanks Jason