vSphere Lifecycle Manager (vLCM) allows users to upload an ESXi component into its depot using the Import Updates operation in the vSphere UI, but deleting an ESXi component from the vLCM depot is currently not possible when using the vSphere UI.
However, using the vLCM REST API we can delete an ESXi component from the vLCM depot with the Settings Depots Offline APIs. To demonstrate these specific vLCM REST APIs, I will be using PowerCLI (Connect-CisServer) but you can also use the vLCM REST API directly via any REST Client.
Step 1 - We first need to find our specific ESXi component and its ID by using the List Depots Offline API. By default, you will find ESXi components that are uploaded by users as well as ESXi components that are managed by vCenter Server such as the vSphere with Tanzu and vSphere HA ESXi components. The easiest way to filter out the managed ESXi components is by looking at the ESXi component owner. In my example, I am filtering by administrator account but you can certainly filter by other users who may have uploaded an ESXi component into vLCM.
$owner = 'administrator[at]vsphere[dot]local' $offlineDepotService = Get-CisService -Name com.vmware.esx.settings.depots.offline $allComponents = $offlineDepotService.list() $results = @() foreach ($component in $allComponents.GetEnumerator()) { if($component.Value.owner.toLower() -eq $owner) { $tmp = [PSCustomObject] @{ ComponentId = $component.Key } $results += $tmp } } $results
As you can see from the output above, there are two ESXi components that match the filter. Ideally, this is the only vLCM API that is required to find the specific ESXi component and its ID, but I found out that the vLCM UI currently does not use the description field from an uploaded ESXi component, which means that the description field is currently left blank and it is impossible to identify the ESXi component that you see in the vSphere UI. I have already filed a feature request to ensure that the vLCM UI will use the description provided by an ESXi component, so that the next step will no longer be required in the future.
Step 2 - With the list of ESXi Component IDs, we now need to use the Get Depots Offline API to check the individual ESXi component to confirm whether that is the ESXi component we wish to delete.
$componentId = "29ABE68C1AE400945FBA10491BA21AB53F9279C3" $offlineDepotContentService = Get-CisService -Name com.vmware.esx.settings.depots.offline.content $componentDetails = $offlineDepotContentService.get($componentId).metadata_bundles $results = @() foreach ($componentDetail in $componentDetails.GetEnumerator()) { foreach ($component in $componentDetail.Value.independent_components.GetEnumerator()) { $tmp = [PSCustomObject] @{ ComponentName = $component.Key ComponentVersion = $component.Value.versions.version ComponentDirectory = $componentDetail.Key ComponentFile = $componentDetail.Value.file_name } $results += $tmp } } $results
As you can see from the output above, the second ESXi component ID is the one we are actually after. In addition to ESXi component name and version, the output also contains two additional fields which might be of interests to those interested in knowing where the ESXi components actually reside within the vCenter Server filesystem. All uploaded ESXi components are stored in a sub-directory under /storage/updatemgr/patch-store/hostupdate and the ComponentFileDirectory provides the name of the sub-directory for that given ESXi component.
In our example, the ESXi component is stored in /storage/updatemgr/patch-store/hostupdate/VMX and the metadata filename which is provided as part of the ComponentFile is called metadata-39.zip. This of course is for informational purposes, you should never manually manipulate the filesystem but instead use the vLCM API as mentioned in this blog post to remove ESXi components that are no longer required.
Step 3 - Lastly, to delete our desired ESXi component, we need to use the Delete Depots Offline API and provide the ESXi component ID.
$componentToDelete = "18EC0E31AA9E1376F099CF2A2528832005D0E961" $offlineDepotService = Get-CisService -Name com.vmware.esx.settings.depots.offline $offlineDepotService.delete($componentToDelete)
edtechlvm says
Everything went through and I was able to delete the two components. However, they still show under the vLCM Image Depot. Any ideas how to refresh or make them disappear? Thank you and great article.
rva says
Same problem for me. Component deleted from the API but is still shown in the web UI.
rva says
Maybe it's due to this:
The task-based {@name #delete} {@term operation} removes content of an imported offline depot from vLCM completely. Note: The non task-based {@name #delete} {@term operation} has been deprecated. It deletes only the record of depot from the list of imported offline software depots, instead of removing the depot's content from vLCM.
Jorge DIAS says
Hello,
Do you know how to perform a task-based instead of a non task-based?
I followed William's procedure using the local administrator with the necessary privileges but the content was not removed only the record.
Regards,
Jorge
MatthewPowerPlug says
Here is how to do a task-based Offline.delete including tracking the task (replace component to delete with proper Key value):
$componentToDelete = '18EC0E31AA9E1376F099CF2A2528832005D0E961'
$offlineDepotService = Get-CisService -Name com.vmware.esx.settings.depots.offline
$tasksService = Get-CisService -Name com.vmware.cis.tasks
Delete component including files...
$tasksService.get($taskId = $offlineDepotService.'delete$task'($componentToDelete))
should show info that includes fields with 10% complete running task:
progress : @{Help=; total=100; completed=10; message=}
status : RUNNING
Checking same task right after...
$tasksService.get($taskId)
should show info that includes fields with 100% complete:
progress : @{Help=; total=100; completed=100; message=}
status : SUCCEEDED
If you want to look at files before and confirm they are indeed deleted after, while logged into vCenter shell, look under directory tree:
/storage/updatemgr/patch-store/hostupdate
Marcelo says
Hello William
Let me bring a scenario here ...
We usually remove the vwmare-tools form our images ...we can still remove it form ISO files but from depot files i observed that even forcing this removal the vmware-tools still be there but as "ReservedVibList"....
And with this new method to update hosts/clusters using images instead baselines seems to me that is by design and its no possible to keep the esxi without vmware-tools .....
do you know something ??
I.E => ReservedVibList : {tools-light 12.3.0.22234872-22380479}
tks
MatthewPowerPlug says
Thanks much to William for this post! It allowed me to find/delete imported card drivers that had the same exact names/versions showing in the vSphere GUI, but one was for ESXi 7 (which I wanted to delete to avoid confusion) and other for ESXi 8.
I used information from this post to gather more details in one loop to make it easier to find the component details. Here is PowerCLI code that can be used to gather/view details:
Connect-CISserver 'vcenter-name-here'
$offlineDepotService = Get-CisService -Name com.vmware.esx.settings.depots.offline
$offlineDepotContentService = Get-CisService -Name com.vmware.esx.settings.depots.offline.content
$depotUploads = [System.Collections.Generic.List[PSCustomObject]]::new() ; `
$offlineDepotService.list().GetEnumerator() | Where-Object { $_.Value.owner -ne 'com.vmware.vcIntegrity' } | ForEach-Object {
$componentDetails = $offlineDepotContentService.get($_.Key).metadata_bundles
$depotUploads.Add([PSCustomObject] @{
ComponentKey = $_.Key
ComponentOwner = $_.Value.owner
ComponentSourceType = $_.Value.source_type
DetailKey = $componentDetails.Keys.Value
FileName = $componentDetails.Values.file_name
UpdateKey = $componentDetails.Values.updates.Keys.Value
UpdateSummary = $componentDetails.Values.updates.Values.summary
IndCompKey = $componentDetails.Values.independent_components.Keys.Value
IndCompName = $componentDetails.Values.independent_components.Values.display_name
IndCompDispVer = $componentDetails.Values.independent_components.Values.versions.display_version
IndCompVer = $componentDetails.Values.independent_components.Values.versions.version
BaseImgName = $componentDetails.Values.base_images.display_name
BaseImgDispVer = $componentDetails.Values.base_images.display_version
BaseImgVer = $componentDetails.Values.base_images.version
})
}
$FormatEnumerationLimit = -1
$depotUploads
From the vCenter shell, find and view the metadata zip files as listed in the gathered info:
find /storage/updatemgr -name metadata\*
unzip -l /storage/updatemgr/patch-store/hostupdate/{DetailKey}/{FileName}
This shows .vib files for DetailKey 'vmw':
ls -l /storage/updatemgr/patch-store/hostupdate/vmw/vib20/*
See my other comment on how to use 'delete$task' to do task-based delete of a ComponentKey's info/files from vCenter.