Get-EsxCli oh my!

This post is the first detailed post coming out of my presentation Ditch the UI – vSphere Management with PowerCLI at the CT VMUG Usercon. Stay tuned for the full bakers dozen of code posts!

esxcli, oh my…

I was finishing a task the day before my presentation, at the CT VMUG usercon – Ditch the UI when I happened to come across the cmdlet Get-ESXCli. My first thought was “No. Really? This command exists and I’m just finding out about it now?” sigh…

But yes it’s true, the fine folks on the PowerCLI provided us this cmdlet some time ago, and I’m just learning about it now. Well, better late than never as they say.

Before we go any further, let’s take a minute to talk about esxcli. ESXCLI is a command line interface (duh) for ESXi systems. It’s a means to modify the VMHost systems, mostly but not entirely, as it relates to the hardware systems. It’s an early & essential, but limited, way of configuring some of the management elements for your ESXi hosts.

Now I mention it’s limitations because they are essential to our story. The first big limitation is the structure of tool. It’s structure is that of namespaces with a hierarchical tree. This means that when you want to access, oh I don’t know, VMFS information/properties/methods you had to know that VMFS exists as a sub-namespaces under the esxcli storage namespace. Not a big deal and some folks actually like the structure, although it’s never really work for me.

Of bigger concern with esxcli, is locality. What I mean is that it was difficult to manage multiple systems. Of course you had options like the vMA or vCLI, but again you’re limited with connectivity options. And it was ugly to programatically try to get around these limitations.

Needless to say I was stoked to come across get-esxcli the other day.

Get-ESXCli! Oh My!!!

I’m a tinkerer. When I see a new toy, I just want to fiddle with it. That being said, I also know from experience (good and bad) what you can do with esxcli, so my first stop on Wednesday was get-help.

2018-03-02 21_27_50-Windows PowerShell

Not terribly helpful… I guess we have no choice but to dive in. To start off, I saved the output of get-esxcli to a variable.

$esxcli=get-esxcli -VMHost $vmhost -V2

Now that we’ve got esxcli (see what I did there?) stored as an object, let’s see what we can do. First things first, echo it back to the screen to see what we get right out of the gate.

esxcli

Ok… well, this gives me something to go off of. It looks just like the structure of esxcli. I suppose that this shouldn’t be shocking, but it certainly is reassuring that we’re treading in semi-familiar territory. So it’s probably save to start moving down the tree.

esxcli_network_nic

Thank you Jeffrey Snover and team for allowing us to experience the wonders of things like tab complete and accessing sub-elements via the dot operator. So looking at a the output of $esxcli.network.nic we see that we can access things like TCP Segmentation Offload and VLAN’s. We get a few direct methods against our current level of the tree in addition to a Help() method.

esxcli_network_nic_help

OK, so this is starting to make a little more sense now. We’re basically taking the same namespaces and methods, but just making them look like PowerShell. At this point I figured I was good to go and just started firing off commands… which resulted in a lot of red text. After one of my frustrating attempts I actually paid attention to what tab-complete was showing me

esxcli_network_nic_down_authcomplete

Hey there “Invoke”? What are you doing there? How come I haven’t seen you in these parts before? After a few tests to get the syntax down, I learned that the .Invoke() method is how we actually get work done, and I can get down to the task I’d originally been so happy to automate.

Accessing the VAAI primitive

Ok, so I wasn’t quite ready to get to work yet.

$esxcli.storage.vmfs.unmap.Help()

After checking out help, just to make sure, I was ready to go…

Here’s my first script using the get-esxcli cmdlet. My whole intent was to programmatically go through my datastores, which resided on a thin-provisioned SAN, to free up any space that needed reclamation.

### Disclaimer. This one needs work, I was just so excited to learn about this cmdlet! To be continued....
Set-PowerCLIConfiguration -WebOperationTimeoutSeconds -1 -Scope Session -Confirm:$false

foreach ($cluster in $(get-cluster)){
  $dsarray=get-cluster $cluster|get-datastore
  $vmhost=get-cluster $cluster|Get-VMHost|select -First 1
  $esxcli=get-esxcli -VMHost $vmhost -V2
  foreach ($ds in $dsarray|where{$_.Type -eq 'VMFS'}){
      $esxcli.storage.vmfs.unmap.Invoke(@{reclaimunit = 60; volumelabel =$ds.name})
  }
}

I went at this script knowing that my storage volumes were mapped to all hosts in each of my clusters. If you weren’t in a similar vanilla situation you’d have to get a bit tricksier with your selection logic. However with knowledge of my environment at hand it was pretty simple to:

line 4: Iterate through each of my clusters.
line 5: Get each datastore for the specified cluster
line 6: Get the first VMHost in the cluster. This is ok because I know that all datastores are associated with all hosts in a given cluster.
line 7: Use our new friend get-esxcli against the previously retrieved VMHost.
lines 8-10: Iterate through each datastore in the cluster and run leverage the invoke method against the VMFS UNMAP primative
$esxcli.storage.vmfs.unmap.Invoke(@{reclaimunit = 60; volumelabel =$ds.name})

With that I was able to return a not insignificant amount of freed up space back to my array. After writing PowerShell code leveraging PowerCLI for the last few years, I’m feeling like I have a new array of opportunities open to me after newly discovering the Get-ESXCli cmdlet.

Happy scripting!

Scott

 

Leave a comment