Enable or Disable VAAI on multiple ESXi hosts

Occasionally storage vendors will request that VAAI be disabled during SAN maintenance.  I wrote a simple script to facilitate toggling the VAAI state for all ESXi hosts in a logical data center.

Download the script from my Github repository here:

As a point of interest, I use a PowerShell feature called ParameterSets.  ParameterSets facilitate grouping cmdlet parameters into mutually exclusive sections.  The PowerShell engine will determine which ParameterSet applies based on the parameters provided by at runtime.

As you can see, I assigned EnableVAAI and DisableVAAI into unique parameter sets.  Only one parameter set is active, forcing the user to choose between -DisableVAAI or -EnableVAAI when executing the script.




Who created all these VMs?

I had a customer ask for a report of who built all VMs in a particular vCenter instance.  Alan of Virtu-Al.net has a great article on how to tag VMs with creator information, here: https://www.virtu-al.net/2010/02/23/who-created-that-vm/

In my case however, I wanted a complete report of all VMs created in the environment, and I wanted it fast.  I opted to go straight to the source… the database.  This SQL query will do the trick:

Using Alan’s article, I compiled a list of interesting event types and added the “vim.event” prefix, as used in the database.  Easy.

One final note:  You may or may not have a complete history in the VPX_EVENT table.  The vCenter with a Microsoft SQL database has a stored procedure “cleanup_events_tasks_proc,” and corresponding SQL Agent job.  This will purge your event history based on two parameters.  You can check the relevant parameters with this query:

Here’s sample output.  In this case purging VPX_EVENT based on event age is disabled:

Powershell string manipulation timing

Seems like these are all about the same speed, except the last one is a little bit faster.

The setup:

We call this one “Jason’s method”

This is a little bit faster (about 1 second faster over 500,000 iterations)

List DRS Host Affinity Rules for specific VM name pattern match

I had a use case for a customer requiring a consistent VM to host affinity rule to be applied across a large environment.  I wrote this script to collect their current configuration.

More importantly, I used a couple techniques here which I will highlight below.

First, I use regex style match to select only the VMs I want:

This will match any VM name containing server1env or server2env, because of the character set specified in brackets.

Then I filter based on the VM’s power state:

This is a simple Where-Object filter for the VM PowerState property.

Using a foreach loop (% is an alias to the ForEach-Object cmdlet), I process each VM.  Here’s an expanded version of the core conditional logic:

Let’s take that one part at a time.  First we determine if a DRS VM to host affinity rule exists for the input VM, which is in the object $_.

Get-DrsRule requires several parameters.  By default, it ignores VM to host affinity rules, so we must explicitly specify that type.  I pass the VM object to filter for rules pertaining to the VM of interest.

Get-DrsRule also requires a cluster specification.  We get this from the “parent” property of the VM’s ESXi host, with $_.VMHost.Parent.  This is probably a cluster, but could be some other type of object in some scenarios.

If this cmdlet returned a non-null result, we combine some interesting information into a PowerShell custom object.  This method enables us to combine the name of the interesting VM, the name of the DRS rule, and some other information returned by the Get-DrsRule cmdlet.

I pipe this into a select-object cmdlet, to enforce property display order and make my output pretty.

If Get-DrsRule doesn’t find any rule matching our criteria, it returns null.  The conditional if statement outputs a string object indicating this result:

I’m using $( ) in the string to embed $_.Name appropriately.

Hope this helps…