DRSRule – a DRS rules and groups module

One of the nice vSphere features is the ability to define DRS rules.

DRSRule-introThe 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:

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:

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:

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

If you picked another folder, you should use the full path to the folder that contains the module’s files, like:

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.

The DRSRule module was set up as community resource, so we are hoping to see your comments, suggestions and code.

Enjoy !

56 Comments

    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:

    1. Is the folder where you stored the DRSRule files present in the $PSModulePath variable ?
    2. Which PowerShell version are you using ? Do a $PSVersionTab
      1. 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

Leave a Reply

Your email address will not be published. Required fields are marked *

*
*

This site uses Akismet to reduce spam. Learn how your comment data is processed.