Product and service reviews are conducted independently by our editorial team, but we sometimes make money when you click on links. Learn more.

How to Access ESXCLI with PowerCLI

By - Source: Toms IT Pro

PowerShell's PowerCLI can be an door into ESXCLI command line interface.

If you have worked with vSphere, chances are you have had to perform some tasks on an ESXi host using ESXCLI. This command line interface created by VMware enables you to perform such tasks as installing software, configuring NIC adapters or seting firewall rules on ESXi. Since ESXi runs only Linux, using ESXCLI can be a bit daunting for Windows admins who don’t have much experience with Linux. Luckily, if you know PowerShell, you can use PowerCLI as a door into ESXCLI.

MORE: Windows 10 for IT Pros: Tutorials, Tips and Tricks

Connecting to an ESXi host

First, we need to connect to either a vCenter server or ESXi host. We can do this with the Connect-VIServer cmdlet. Keep in mind you can also connect to your vCenter server as well.

Connect-VIServer -Server devhost -Credential (Get-Credential)

Exposing ESX CLI

Now that we are connecting to our ESXi host "Devhost" we can use the Get-EsxCli cmdlet in PowerCLI to expose the ESXCLI functionality by placing it into a variable.

$DevHost = Get-EsxCli -VMHost devhost -V2

Notice I used the –V2 parameter. This means we are using version 2 of this cmdlet as version 1 is deprecated and compatibility is not guaranteed.

Now if we just run the output of $DevHost we see the "elements" we have to work with for this ESXi host.

$DevHost = Get-EsxCli -VMHost devhost -V2

C:> $DevHost

EsxCli: devhost


To see what tasks you can do with each element, we can drill down by running $DevHost.<element> to view the CodeMethods and CodeProperties. For instance, if I run $DevHost.system.account | Get-Member –MemberType Code* I will see that I can add, list, remove and set accounts on this host.

  C:> $DevHost.system.account | Get-Member -MemberType Code*

   TypeName: VMware.VimAutomation.ViCore.Impl.V1.EsxCli.EsxCliElementImpl

Name   MemberType   Definition
----         ----------      ----------
Help      CodeMethod     string Help()
add       CodeProperty    VMware.VimAutomation.Sdk.Util10Ps.ObjectCustomization.SimpleExtensionProperty
list        CodeProperty    VMware.VimAutomation.Sdk.Util10Ps.ObjectCustomization.SimpleExtensionProperty
remove  CodeProperty   VMware.VimAutomation.Sdk.Util10Ps.ObjectCustomization.SimpleExtensionProperty
set        CodeProperty    VMware.VimAutomation.Sdk.Util10Ps.ObjectCustomization.SimpleExtensionProperty

Removing VIBS

So, let’s say, for instance, I am having an issue with a VIB and I want to remove it, in this case the Dell OpenManage agent for ESXi. First, I need to find the name of the VIB. I can do this by piping a list of VIBS to the Where-Object cmdlet:

$ | Where-Object {$_.Name -like "*OpenManage*"}

AcceptanceLevel : PartnerSupported
CreationDate    : 2015-07-29
ID              : Dell_bootbank_OpenManage_8.2.0.ESXi600-0000
InstallDate     : 2016-09-08
Name            : OpenManage
Status          :
Vendor          : Dell
Version         : 8.2.0.ESXi600-0000

I find the name of the VIB is "OpenManage". Now I can remove this VIB by using the Invoke() method but it needs some arguments in the form of a hash table. To find what arguments I can run I can use the Help() method:

So it appears one of the parameters is "dryrun", which will let me see the result of removing the VIB but not make system changes. This is similar to a -Whatif parameter in PowerShell.

C:> ${'dryrun' = $True;'force' = $False;'maintenancemode' = $False;'noliveinstall' = $False;'vibname' = 'OpenMan
age' })

Message        : Dryrun only, host not changed. The following installers will be applied: [BootBankInstaller]
RebootRequired : true
VIBsInstalled  :
VIBsRemoved    : {Dell_bootbank_OpenManage_8.2.0.ESXi600-0000}
VIBsSkipped    :

The result of the dry run looks good. So I will remove the VIB by just switching ‘dryrun’ to $True.

C:> ${'dryrun' = $False;'force' = $False;'maintenancemode' = $False;'noliveinstall' = $False;'vibname' = 'OpenMa
nage' })

Message        : The update completed successfully, but the system needs to be rebooted for the changes to be effective.
RebootRequired : true
VIBsInstalled  :
VIBsRemoved    : {Dell_bootbank_OpenManage_8.2.0.ESXi600-0000}
VIBsSkipped    :

Get system time

Retrieving the system time on an ESXi host is very simple because there are no parameters for the Invoke() method.

C:> $DevHost.system.time.get.Invoke()

View running processes

Have you ever wondered what processes are running on your host at the moment? Using PowerCLI we can get a list of processes with names and id:

C:> $DevHost.system.process.list.Invoke() | Select-Object -Property Name,id | Sort-Object -Property Name

Pinging other hosts

As illustrated by Alan Renouf, there is a very innovative way to ping others hosts using Get-EsxCli.

First, we create a hash table of our arguments needed with CreateArgs():

C:> $arguments = $

Next, we set the value of the host we want to ping, in this case

C:> $ = ''

Finally, we pass the hash table of arguments to Invoke() and pipe to Select-Object to view the output of our ping. We see that all pings were transmitted successfully.

C:> $$arguments) | Select-Object -ExpandProperty Summary

Duplicated     : 0
HostAddr       :
PacketLost     : 0
Recieved       : 3
RoundtripAvgMS : 6762
RoundtripMaxMS : 7310
RoundtripMinMS : 6296
Transmitted    : 3

Automating pings from every host

For this example I want to see if all my ESXi hosts can ping a particular IP address, for instance a server hosting an NFS share.
First, I will connect to my vCenter server in PowerCLI:

C:> Connect-VIServer vcenter

Next, let’s place all my hosts into the $ESXiHosts variable with Get-EsxCLI:

C:> $ESXiHosts = Get-EsxCli -VMHost (Get-VMHost) -V2

Now I will run a one-liner in PowerCLI to attempt a ping from all my hosts to the IP address in my $Arguments hash table. The output will be the hostname of each ESXi host and the number of pings received by the destination.

C:> $ESXiHosts | ForEach-Object {$Received = ($$arguments) | Select-Object -ExpandProperty Summary).Recieved;$VMHost = $_.VMHost.Name;Write-Output "$VMHost,$Received"}