In this final three part esxcli series, I will show you how to automate esxcli operations in a Windows environment using PowerShell. There was a recent question on the VMTN forums regarding this very topic. As a simple solution to the problem, a community member provided a snippet of PowerShell code. Of course the snippet of PowerShell code originated from the great PowerCLI Master - Luc Dekens.
I have slightly modified the original version of the script as I am not a fan of hard coding passwords within a script. This version of the script requires plink which is a command-line interface to the free Windows SSH PuTTY back end. The script performs an SSH connection to either an ESX or ESXi host to run esxcli command locally, with the specified parameters as you would if you were on the Service Console, or the unsupported Busybox console.
Copy the snippet of code below and create a new script called esxcli-automation1.ps1 and replace all the variables matching your environment including the $cmd which specifies the exact esxcli command you are running on the remote host.
esxcli-automation1.ps1
$User = "root" $Computer = "esxi4-1.primp-industries.com" #prompt user for password $passwordInput = Read-Host -AsSecureString:$true "Please enter password for $Computer" #convert secure password to normal string $Ptr = [System.Runtime.InteropServices.Marshal]::SecureStringToCoTaskMemUnicode($passwordInput) $Password = [System.Runtime.InteropServices.Marshal]::PtrToStringUni($Ptr) [System.Runtime.InteropServices.Marshal]::ZeroFreeCoTaskMemUnicode($Ptr) $plink = "C:\plink.exe" $esxcli = "esxcli" $plinkoptions = " -v -batch -pw '$Password'" $cmd = 'nmp device list' $remoteCommand = $esxcli + " " + '"' + $cmd + '"' $command = $plink + " " + $plinkoptions + " " + $User + "@" + $computer + " " + $remoteCommand Invoke-Expression -command $command
Here is a sample execution listing devices:
There are a few issues with this script:
- Assumes SSH connectivity is open to the host, which on classic ESX w/Service Console is probably a valid reason but what about ESXi? We know that we should not be using the unsupported Busybox console on ESXi and we can not make the assumption that it will be opened
- The script can only execute against one host at a time.
In a perfect world, the esxcli API would be properly exposed and integrated into the vSphere API. PowerCLI and other vSphere SDKs would be able to automate these configurations without this hack, but unfortunately this is not the case. However, we can leverage the esxcli utility that is bundled up with the vCLI which can be installed on either a Linux or Windows platform.
With this information, I decided to write my own PowerShell script (yes you heard right, it was slightly difficult without knowing the syntax and format) matching the capabilities similar to that of the vSphere SDK for Perl implementation running on vMA. So here is the second revision of the script called esxcli-automation2.ps1:
esxcli-automation2.ps1
$Username = "root" $esxcli = "C:\Program Files\VMware\VMware vSphere CLI\bin\esxcli.exe" #$Params = "swiscsi nic list -d vmhba33" #list of ESX and ESXi host to perform operation against $vihosts = @("esxi4-1.primp-industries.com","esxi4-3.primp-industries.com") #prompt user for password $passwordInput = Read-Host -AsSecureString:$true "Please enter your common password for hosts" #convert secure password to normal string $Ptr = [System.Runtime.InteropServices.Marshal]::SecureStringToCoTaskMemUnicode($passwordInput) $Password = [System.Runtime.InteropServices.Marshal]::PtrToStringUni($Ptr) [System.Runtime.InteropServices.Marshal]::ZeroFreeCoTaskMemUnicode($Ptr) #loop through array of hosts for($i = 0; $i -le $vihosts.length -1; $i++) { write-Host Executing operation on $vihosts[$i] #could not find a way to store the params in a variable you must #insert esxcli parameters at the very end of the statement below & $esxcli --server $vihosts[$i] --username $Username --password $Password swiscsi nic list -d vmhba33 }
Note: PowerCLI is not required, just PowerShell.
This new version of the script allows you specify a list of ESX or ESXi host to perform a common esxcli operation. The script also prompts for the password as the previous script, so you do not have to hard code the password to the host. You will need to update the script with the path to the plink.exe and the list of hosts you want to perform the operation against.
Here is an example of verifying iSCSI multipathing configuration against two hosts (1 ESX and 1 ESXi) without the use of SSH:
As you can see, you can easily integrate this with other existing PowerCLI scripts that perform configuration changes across a given set of host(s). Until VMware provides access to the esxcli APIs, these are some of the methods/hacks that need to be implemented when automating configuration changes using esxcli.
Here are some PowerShell references that were used in creating the two scripts: