Upload and Install ESXi Patch via PowerCLI

The Script I have created a few weeks ago is a little bit more than a simple Upload and Install ESXi Patch via PowerCLI. The Script uses for the installation of the Patch Bundle the VMware PowerCLI ESXCLI v2 Cmdlet (no SSH Connection for esxcli). This method forces the installation of the VIBs in the Patch Bundle and allows also a downgrade of the Version. The Install-VMHostPatch Cmdlet, which is common for the Patch installation with PowerCLI, only applies version updates and does not force a downgrade of a VIB.

Upload and Install ESXi Patch via PowerCLI - Log Output

As a goodie does the script handle the respond of the Patch installation and detects if a reboot is required. If so the host will be restarted.

My initial use case for this script was to standardize all NIC drivers is the whole vCenter inventory. To get this done IO have used my  NIC Driver and Firmware function to get all ESXi hosts with wrong NIC driver Version (and also wrong firmware) to get them all to the recommended version (up- and downgrade was necessary).

Upload and Install ESXi Patch via PowerCLI Script

The PowerCLI script installs the Patch bundle from a Datastore on all ESXi Hosts of the vSphere Cluster in Maintenance Mode. The file must be uploaded to the Datastore before the installation.


Name Description Example
ClusterName Name of the vSphere Cluster “Compute01”
LocalPath Local path to the Patch Bundle “D:\Image\HPE-20180220.zip”
DepotName Name of the Depot Zip file “HPE-20180220.zip”
TempDatastoreName Name or wildcard of the Datastore “LOCAL*”

For the upload of the ZIP file i use the New-DatastoreDrive and Copy-DatastoreItem Cmdlets. After that the Installation will be done by the Get-ESXCLI -V2 Cmdlet.

[String]$ClusterName = "Compute01"
[String]$LocalPath = "D:\Image\HPE-20180220.zip"
[String]$DepotName = "HPE-20180220.zip"
[String]$TempDatastoreName = "LOCAL*"

$VMhosts = Get-Cluster -Name $ClusterName | Get-VMHost | Where-Object {$_.ConnectionState -eq "Maintenance"}

foreach ($VMhost in $VMhosts) {
    #region: Upload Patch
    $Datastore =  $VMhost | Get-Datastore -Name $TempDatastoreName
    $DatastoreDriveName = "HostStore_" + $VMhost.Name.Split(".")[0]
    $Datastore | New-DatastoreDrive -Name $DatastoreDriveName | Out-Null
    Copy-DatastoreItem -Item $LocalPath -Destination $($DatastoreDriveName + ":\") -Force:$true -Confirm:$false
    Remove-PSDrive -Name $DatastoreDriveName

    #region: Install Host Patch
    $HostPath = $Datastore.ExtensionData.Info.Url.remove(0,5) + $DepotName
    $esxcli2 = Get-ESXCLI -VMHost $VMhost -V2
    $CreateArgs = $esxcli2.software.vib.install.CreateArgs()
    $CreateArgs.depot = $HostPath
    $InstallResponse = $esxcli2.software.vib.install.Invoke($CreateArgs)

    #region: Restart Host
    if ($InstallResponse.RebootRequired -eq $true) {
        Write-Host "Rebooting '$($VMHost.Name)'..."
        Write-Host "VIBs Installed:"

        $VMhost | Restart-VMHost -Confirm:$false | Out-Null    
    else {
        Write-Host "No Reboot for '$($VMHost.Name)' required..."    

This Script is also available as GitHub Gist

Leave a Reply