In many environments after installing the stock ESXI image you end up wanting perform an update with the latest patches, update drivers and maybe even remove drivers. VMware’s Image Builder PowerCLI cmdlets provide a method of taking a stock ESXI image and performing such tasks, resulting in a customised ISO that’s ready for deployment, hopefully saving time when building up a new ESXi server. A custom ISO, together with AutoDeploy could mean that you have a fully automated method of building that ESXi server.
Below I walk through the creation of a customised ESXi ISO. Starting off with obtaining the drivers and updates that you may want to include through to the creation of the ISO using VMware’s Image Builder PowerCLI cmdlets.
To start, you’ll need to download your base installation that you want to customise. Head over to VMware.com and download the offline bundle of the version of ESXi that you want to install. Eg,
If you are installing on hardware for which a custom ISO is provided, I would recommend that is used over the stock VMware image. The custom vendor ISO will come shipped with their relevant drivers and updates making your life that little bit easier. I’ll be using a custom HPE image
At this point I’d also recommend reviewing what patches have been made available since the release of the bundle to see if there area any that you’d like to include in your new image. You can head on over to the Product Pages portal at https://my.vmware.com/group/vmware/patch to review and download any updates.
Select the updates that you require and download locally to c:\temp\updates. We’ll be integrating these into our ESXi image as part of our script.
To demonstrate further what can be integrated, we’ll download the Teradici Apex Card driver and integrate that into our image. You should download your vendor driver bundles and copy them to c:\temp\driver. I’ll be using:
c:\temp\driver\apex2800-rel-2.5.3.46443-esxi.5.5.0.zip
Terminology Sidebar
- VIB:software packages. vendors release vibs to extend or repair the ESXi platform
- Image Profile:logical collection of VIBs.
- Software Depot:collection of VIBs and Image Profiles. Offline depot (.zip), online depot (URL). Export Depot to .ISO
That’s the downloads taken care of, lets start with the script.
Initialise some variables that we’ll be using. I’ve used c:\temp as my base directory for the images, drivers and updates. You can change this as required. There are also a few options to determine if you are to include VMware Tools and whether or not only security updates (and therefore not bug fixes) are to be integrated.
1 2 3 4 5 6 7 8 9 10 11 12 |
#INITIALISE VAIRABLES $offlineDepot = "C:\temp\VMware-ESXi-6.0.0-Update2-3620759-HPE-600.9.5.0.48-Apr2016-depot.zip" $imgprofilename = "My HPE VMware-ESXi-6.0.0-Update2" #this can be whatever you want to call the profile $vcenter = "vcenter.domain.local" $updatespath = "c:\temp\updates" $driverpath = "c:\temp\driver" $exportpath = "c:\temp" #OPTIONS $withtools = $true #use profile with VMtools or not $exportiso = $true #export iso $securityonly = $false #security only profiles |
Onto clearing any previous depots and adding our new one
1 2 3 4 5 6 7 8 9 10 |
#clean the decks Get-EsxSoftwareDepot | Remove-EsxSoftwareDepot #add the depot Add-EsxSoftwareDepot $offlineDepot #view available images in added depots and select the appropriate one $baseprofile = Get-EsxImageProfile | select * | Out-GridView -PassThru #create the image profile #this is a grouping of all the vibs for the install #clone a profile from the vendor image as a base to work from New-EsxImageProfile -CloneProfile $baseprofile.Name -Name $imgprofilename -Vendor $baseprofile.vendor |
Here we added the offline depot from HPE, selected an image profile and then created a clone of it and this is profile that we’ll we updating.
Lets take this opportunity to take a close look at depots and their images. We’ll do this by looking at the stock ESXi 6u2
1 2 |
Add-EsxSoftwareDepot VMware-ESXi-6.0.0-2494585-depot.zip Get-EsxImageProfile | select name, vendor | Sort-Object Name | Format-Table -AutoSize |
This results in the following output
This tells us that within the offline depot there are 2 image profiles; 1 standard and 1 with no tools. Image profiles are simply logical groupings of software. For example, offline bundles for ESXi updates may also contain profiles for security only and security+fixes
In our v6 example, we have two profiles one with VMtools and one without. The no-tools version is usually smaller and has less memory overhead, well suited to quick deployments with Auto Deploy.
Back to our script
1 2 3 |
#add in the HA agent to the profile Add-EsxSoftwareDepot "http://$vcenter/vSphere-HA-depot" Add-EsxSoftwarePackage -ImageProfile $imgprofilename -SoftwarePackage vmware-fdm |
Next we add in the VMware HA agent (vmware-fdm) into the profile. If you plan to create a HA Cluster then this will save time enabling HA. The agent is pulled directly from your vCenter server.
1 2 3 4 5 6 |
#get updates from folder $updateFromFolder = gci $updatespath -Filter *.zip #add in the update depots $updateFromFolder.FullName | % { $addDepot = Add-EsxSoftwareDepot $_ } |
Before we started we collected together the updates that we wanted to add into our new ESXi image. Above we cycle through all the updates in the folder and add those depots into our session.
1 2 3 4 5 |
if ($withtools -eq $true) {$toolsFilter = "-standard" }else {$toolsFilter ="-no-tools"} if ($securityonly -eq $false) {$securityFilter = "[^s]-(\D*)$"} else {$securityFilter = "s-(\D*)$"} #get all profiles that are now loaded that do not #include the vendor and our new one $allImageProfiles = Get-EsxImageProfile | ? {($_.Name -ne $baseprofile.Name) -and ($_.Name -ne $imgprofilename) -and ($_.Name -match $toolsFilter) -and ($_.Name -match $securityFilter)} |
Collect the image profiles that we are interested in. Filter for security and tools, and also exclude the vendor image profile that we imported in the first place. We should be left with the profiles that correspond to the updates that we want to include.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
#cycle through the image profiles #collect new packages and add to baseprofile $allImageProfiles | % { $thisprofile = $_ $delta = Compare-EsxImageProfile -ReferenceProfile $baseprofile.Name -ComparisonProfile $thisprofile.Name $deltaupdates = $delta | select -ExpandProperty UpgradeFromRef #upgrade vibs $deltaupdates += $delta | select -ExpandProperty OnlyInComp #new vibs if ($deltaupdates) { foreach ($d in $deltaupdates) { $pkg = Get-EsxSoftwarePackage | ? {$_.Guid -eq $d} Write-Verbose "Adding $pkg to $imgprofilename" -Verbose Add-EsxSoftwarePackage -ImageProfile $imgprofilename -SoftwarePackage $pkg } } } |
Here we do a comparison between the update profiles and our base profile to establish what software (VIBs) are different. The collection of required software VIBs are then added to our base profile. (Credit to virtu-al.net)
1 2 3 4 5 6 7 8 9 |
#Apex Driver $driversFromFolder = gci $driverpath -Filter *.zip $driversFromFolder.FullName | % { $addDepot = Add-EsxSoftwareDepot $_ $addDepot | Get-EsxSoftwarePackage | % { Add-EsxSoftwarePackage -ImageProfile $imgprofilename -SoftwarePackage $_.Name } } |
We use the same technique to add the driver to the base profile
1 2 3 4 5 |
#Export ISO + Bundle Export-EsxImageProfile -ImageProfile $imgprofilename -ExportToBundle -FilePath $($exportpath + "\" + $imgprofilename + ".zip") if ($exportiso -eq $true) { Export-EsxImageProfile -ImageProfile $imgprofilename -ExportToISO -FilePath $($exportpath + "\" + $imgprofilename + ".iso") } |
Finally we export out the ISO and offline bundle. It’s a good idea to export out the bundle as you can use this when you want to make further incremental updates. This ISO can now be used to install ESXi onto your hardware, whether that be through a manual method or using Auto Deploy.
Here is the complete script (use the controls at the top of the script to expand, copy etc.)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
#INITIALISE VAIRABLES $offlineDepot = "C:\temp\VMware-ESXi-6.0.0-Update2-3620759-HPE-600.9.5.0.48-Apr2016-depot.zip" $imgprofilename = "My HPE VMware-ESXi-6.0.0-Update2" #this can be whatever you want to call the profile $vcenter = "vcenter.domain.local" $updatespath = "c:\temp\updates" $driverpath = "c:\temp\driver" $exportpath = "c:\temp" #OPTIONS $withtools = $true #use profile with VMtools or not $exportiso = $true #export iso $securityonly = $false #security only profiles #SCRIPT #clean the decks Get-EsxSoftwareDepot | Remove-EsxSoftwareDepot #add the depot Add-EsxSoftwareDepot $offlineDepot #view available images in added depots and select the appropriate one $baseprofile = Get-EsxImageProfile | select * | Out-GridView -PassThru #create the image profile #this is a grouping of all the vibs for the install #clone a profile from the vendor image as a base to work from New-EsxImageProfile -CloneProfile $baseprofile.Name -Name $imgprofilename -Vendor $baseprofile.vendor #add in the HA agent to the profile Add-EsxSoftwareDepot "http://$vcenter/vSphere-HA-depot" Add-EsxSoftwarePackage -ImageProfile $imgprofilename -SoftwarePackage vmware-fdm #get updates from folder $updateFromFolder = gci $updatespath -Filter *.zip #add in the update depots $updateFromFolder.FullName | % { $addDepot = Add-EsxSoftwareDepot $_ } if ($withtools -eq $true) {$toolsFilter = "-standard" }else {$toolsFilter ="-no-tools"} if ($securityonly -eq $false) {$securityFilter = "[^s]-(\D*)$"} else {$securityFilter = "s-(\D*)$"} #get all profiles that are now loaded that do not #include the vendor and our new one $allImageProfiles = Get-EsxImageProfile | ? {($_.Name -ne $baseprofile.Name) -and ($_.Name -ne $imgprofilename) -and ($_.Name -match $toolsFilter) -and ($_.Name -match $securityFilter)} #cycle through the image profiles #collect new packages and add to baseprofile $allImageProfiles | % { $thisprofile = $_ $delta = Compare-EsxImageProfile -ReferenceProfile $baseprofile.Name -ComparisonProfile $thisprofile.Name $deltaupdates = $delta | select -ExpandProperty UpgradeFromRef #upgrade vibs $deltaupdates += $delta | select -ExpandProperty OnlyInComp #new vibs if ($deltaupdates) { foreach ($d in $deltaupdates) { $pkg = Get-EsxSoftwarePackage | ? {$_.Guid -eq $d} Write-Verbose "Adding $pkg to $imgprofilename" -Verbose Add-EsxSoftwarePackage -ImageProfile $imgprofilename -SoftwarePackage $pkg } } } #Apex Driver $driversFromFolder = gci $driverpath -Filter *.zip $driversFromFolder.FullName | % { $addDepot = Add-EsxSoftwareDepot $_ $addDepot | Get-EsxSoftwarePackage | % { Add-EsxSoftwarePackage -ImageProfile $imgprofilename -SoftwarePackage $_.Name } } #Export ISO + Bundle Export-EsxImageProfile -ImageProfile $imgprofilename -ExportToBundle -FilePath $($exportpath + "\" + $imgprofilename + ".zip") if ($exportiso -eq $true) { Export-EsxImageProfile -ImageProfile $imgprofilename -ExportToISO -FilePath $($exportpath + "\" + $imgprofilename + ".iso") } |
Permalink //
Thanks for this post. Really cool stuff that is relevant to the newest technologies.
Is the 2nd half of this line meant to be #commented-out? Not sure how to select the desired image.
$baseprofile = Get-EsxImageProfile #| select * | Out-GridView -PassThru
Permalink //
Yup, good spot! Uncommenting that portion will mean that you are presented with a GridView from which you can select your desired profile. (I must have left it uncommented as the HPE image only has one profile. I’ll update the code). Out of curiosity, what image are you customizing?
Permalink //
Customizing a stock ESXi 6.0 image and ‘injecting’ the storage vendor driver and possibly a 2nd driver from another vendor. I was going to test your script to see how it would handle adding (2) different .zip files in the same directory. (from different vendors)
Permalink //
Ah OK, in theory it should work. Let me know the results, I’m happy to help troubleshoot / update the script if need be.
Permalink //
Sandeep, you’re right. It worked seemlessly. I logged in after applying/installing the new OS and verified the vib list and both were listed. Thanks again for this script.
How often do you create new images? Only when a vendor releases an update or do you have different scenarios that come up often? (just curious)
Permalink //
As the process is straight forward I can’t see why the ISO can’t be kept inline with the production environment. So if you patch in production, roll that update into your ISO. Then if you need to re/build a host it won’t require subsequent patching. Extremely useful if you plan to use Auto Deploy (hopefully I’ll write that up too).
Permalink //
very useful
thank you
SP
Permalink //
Hi! Thanks a lot for this useful article! I have a quick question:
I was trying to create custom image, but faced the issue, when I was patching ESXi 6.5 with the latest VIB from VMware 7526125 (2018-01-09).
All async vibs were overwritten and downgraded by this patch, like when you do “esxcli software vib install” instead of “esxcli software vib update”.
Is there any option to patch image without updating async drivers? Just meltdown and spectre fix?
Permalink //
Hey – I’ll try and get a moment to refresh my memory around this (off the VMware scene at the moment). If you figure it out yourself, drop me a note!