PowerCLI

 View Only

 Invoke-ApplyHostSoftwareAsync can't remediate a host with a cluster-level BaseImage

Loic Mahe's profile image
Loic Mahe posted May 23, 2025 05:35 AM

Hello,

I've asked this question to Broadcom support, but it seems they don't have the answer for the moment.

I have defined, at the cluster level, a BaseImage + Vendor Add-On on an existing cluster with two hosts in order to upgrade them.

By using the vCenter UI, I was able to remediate the first host (by selecting the host and not the cluster to remediate).

I wanted to remediate the second host using PowerCLI (because we have several hundred hosts to upgrade and I would like to script it), but I got an error:

Get-Cluster -Name MyCluster | Test-LcmClusterCompliance
Cluster                                      Impact               Status CompliantH NonComplia Incompatib Unavailabl
                                                                               osts    ntHosts    leHosts     eHosts
-------                                      ------               ------ ---------- ---------- ---------- ----------
MyCluster                            RebootRequired         NonCompliant          1          1          0          0
$spec = Initialize-SettingsHostsSoftwareApplySpec -AcceptEula $true

$vmhost = Get-VMHost -Name MyHost2
Invoke-ApplyHostSoftwareAsync -Host $vmhost.ExtensionData.MoRef.Value -SettingsHostsSoftwareApplySpec $spec

Invoke-vSphereApiClient : InvocationException: [UNSUPPORTED]
The host MyHost2 is not a vLCM managed standalone host.
---> System.Net.WebException: Le serveur distant a retourné une erreur : (400) Demande incorrecte.

 Why can we remediate at the host level in vCenter UI but not with PowerCLI?

If I understand well, vCenter UI and PowerCLI are performing the same actions through the same low-level routines.

Regards,

Loïc Mahé

Toulouse, France

p0werShelldude's profile image
p0werShelldude

Hi Loïc

Once you have defined your cluster image, you can leverage the vCenter GUI or PowerCLI to remediate individual hosts. Using PowerCLI requires a little bit more work for error handling, but here is the basic function to do so

function Wait-ForTask ($taskName) {
    do {
        $tasks = Get-Task | Where-Object { $_.ObjectId -match $clusterId -and $_.Name -eq $taskName }
    
        if ($tasks.State -contains 'Running') {
            Write-Host "$taskName is still running on $($vmHost.Name)"
            Start-Sleep -Seconds 60
        }
    } while ($tasks.State -ne 'Success')
}    

function Invoke-VMHostRemediation ($vmHosts) {
    foreach ($vmHost in $vmHosts) {
        $hostId = $vmHost.ExtensionData.MoRef -replace 'HostSystem-', ''

        #Put the host into Maintenance Mode
        Set-VMHost -VMHost $vmHost.Name -State Maintenance -Confirm:$false

        #Ensure the host is in Maintenance mode
        do {
            Start-Sleep -Seconds 60
            Write-Host "Validating that $($vmHost.Name) is in Maintenance Mode"
            $maintenanceModeCheck = Get-VMHost -Name $vmHost.Name
        } until ($maintenanceModeCheck.ConnectionState -eq 'Maintenance')

        $spec = $esxClusterSoftwareService.Help.'apply$task'.spec.Create()
        $spec.accept_eula = $true
        $spec.hosts = @($hostId)

        # Run vLCM Apply/Patch Operation
        Write-Host "Initiating remediation for $($vmHost.Name)"
        $esxClusterSoftwareService.'apply$task'($clusterId, $spec)

        Wait-ForTask -taskName 'Remediate Cluster' 
        Wait-ForTask -taskName 'Check compliance of cluster with image'           
            
        #Take the Host out of Maintenance Mode
        Write-Host "$($vmHost.Name) is exiting Maintenance Mode"
        Set-VMHost -VMHost $vmHost.Name -State Connected -Confirm:$false | Out-Null
        Start-Sleep -Seconds 15
    }        
}


$vCenter = 'vCenterName.FQ.DN'
$cluster = 'ClusterName'

Connect-VIServer -Server $vCenter 
Connect-CisServer -Server $vCenter

$clusterId = (Get-Cluster $cluster | select -ExpandProperty Id) -replace 'ClusterComputeResource-', ''
$vmHosts = Get-View -ViewType HostSystem | Where-Object { $_.Parent -match $clusterId }
$esxClusterSoftwareService = Get-CisService -Name com.vmware.esx.settings.clusters.software

Invoke-VMHostRemediation -vmHosts $vmHosts
Loic Mahe's profile image
Loic Mahe

Hi p0werShelldude and thanks for the answer.

I've already seen this way to perform the remediation in a post by William Lam from 2022, but I thought there would be plain PowerCLI commands by now to do the job.

Regards,

Loïc