There was an interesting discussion on our internal Socialcast platform last week on figuring out how an ESXi host is booted up whether it is from local device like a disk or USB device, Auto Deploy or even boot from SAN along with its respective boot device? Although I had answered the question, I was not confident that we actually had a reliable and programmatic method for identifying all the different ESXi boot methods, which of course piqued my interest.
With a bit of trial and error in the lab, I believe I have found a method in which we can identify the ESXi boot type (Local, Stateless, Stateless Caching, Stateful or Boot from SAN) along with some additional details pertaining to the boot device. To demonstrate this, I have created the following PowerCLI script ESXiBootDevice.ps1 which contains a function called Get-ESXiBootDevice.
The function can be called without any parameters, in which it will query all ESXi hosts for a given vCenter Server and/or standalone ESXi host. You can also specify a specific ESXi host by simply passing in the -VMHostname option.
Here is an example output for one of my lab environments which shows several ESXi hosts and their different boot methods from local disk to Auto Deploy which can include stateless, stateless caching and stateful deployments. Depending on the BootType, the boot device shown in the Device column will either be the MAC Address of the NIC used to network boot the ESXi host or the identifier of a disk device. I have also included some additional details such as vendor/model along with the media type (SAS, SSD or USB) which is available as part of ESXCLI.
This script also supports ESXi environments that boot from SAN (FC, FCoE or iSCSI) and you can easily identify that with the word "remote" for the BootType. I would like to give a huge thanks to David Stamen who helped me out with the boot from SAN testing.
Ananda Kammampati says
Thanks for sharing.
I am guessing an USB boot would then be "BootType = Local" and "IsUSB=true"
William Lam says
Yes, that's correct
Shivakumar Sreedharan says
Yeah..that is how i used to find it.....
Roman Gelman says
Hi William, great idea, BUT:
The `$esxcli.storage.core.device.list.Invoke()` doesn't return `IsBootDevice` property for pre vSphere6.x hosts :-(.
As well as `IsSAS` and many others, 49 properties in vSphere 6.0 vs 33 in vSphere 5.5.
Nicholas Sousa says
You may want to look into ValidateScript for checking your input parameters.
aj mun says
I too get the following error:
You cannot call a method on a null-valued expression.
At C:\admin\00_SETTINGS\_PROFILES\vmware powercli\ESXiBootDevice.ps1:60 char:9
+ $devices = $esxcli.storage.core.device.list.Invoke()
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
I'm running powercli version:
PowerCLI C:\> Get-PowerCLIVersion
PowerCLI Version
----------------
VMware PowerCLI 6.5 Release 1 build 4624819
---------------
Component Versions
---------------
VMware Cis Core PowerCLI Component 6.5 build 4624453
VMware VimAutomation Core PowerCLI Component 6.5 build 4624450
VMWare ImageBuilder PowerCLI Component 6.5 build 4561891
VMWare AutoDeploy PowerCLI Component 6.5 build 4561891
VMware Vds PowerCLI Component 6.5 build 4624695
VMware Cloud PowerCLI Component 6.5 build 4624821
VMware HA PowerCLI Component 6.0 build 4525225
VMware HorizonView PowerCLI Component 7.0.2 build 4596620
VMware Licensing PowerCLI Component 6.5 build 4624822
VMware PCloud PowerCLI Component 6.5 build 4624825
VMware Storage PowerCLI Component 6.5 build 4624820
VMware vROps PowerCLI Component 6.5 build 4624824
VMware vSphere Update Manager PowerCLI 6.5 build 4540462
aj mun says
BTW, changing get-esxcli from -V2 to V1 (by removing the -V2 from the script), provides a completely different output on some hosts. See below to understand what I'm talking about but I've confirmed invidually no the esxi hosts that the v1 form of the script is accurate and somehow v2 is outputing incorrect information:
The esxi hosts below in my environment are the following version:
VMware ESXi 6.0.0 build-3380124
VMware ESXi 6.0.0 Update 1
And yes I know something will be mentioned about me using PowerCLI 6.5 update 1 possibly being the cause but just wanted to point it out....
Host Device BootType Vendor Model SizeMB IsSAS IsSSD IsUSB
---- ------ -------- ------ ----- ------ ----- ----- -----
(using get-esxcli v2 in script)
examplecomputer02.domain.example mpx.vmhba32:C0:T0:L0 local HP 8GB_EM_USB_Drive 7648 false false true
examplecomputer41.domain.example mpx.vmhba32:C0:T0:L0 local HP 8GB_EM_USB_Drive 7648 false false true
examplecomputer42.domain.example mpx.vmhba32:C0:T0:L0 local HP 8GB_EM_USB_Drive 7648 false false true
examplecomputer43.domain.example mpx.vmhba32:C0:T0:L0 local HP 8GB_EM_USB_Drive 7648 false false true
using get-esxcli v1 in script)
examplecomputer02.domain.example naa.600508b1001ce9555e76817a3a6cd886 remote HP LOGICAL VOLUME 858451 true false false
examplecomputer41.domain.example naa.600508b1001ce9555e76817a3a6cd886 remote HP LOGICAL VOLUME 858451 true false false
examplecomputer42.domain.example naa.600508b1001ce9555e76817a3a6cd886 remote HP LOGICAL VOLUME 858451 true false false
examplecomputer43.domain.example naa.600508b1001ce9555e76817a3a6cd886 remote HP LOGICAL VOLUME 858451 true false false
guru says
This script does not seem to be working. Can someone confirm if it has worked for them recently ?
Shaz says
Running on 6.5 U2 hosts - no output - no error
Douglas Ferguson says
Thanks! This is exactly what I am needing for vSphere ESXi 7.0 upgrades. Since the new partition layouts and storage requirements affect our ability to deploy supportable upgrades, this will help us identify hosts we shouldn't be upgrading since that logic seems to be missing from LCM.
One thing I would like to add is to insert a clause so that the script won't try to invoke Get-ESXCli against disconnected, or NotResponding hosts:
if ($VMHost.ConnectionState -in 'Connected', 'Maintenance') {
#do your collection stuff and add the pscustomobject to the $Results variable
}
I also changed my "copy" to use [System.Collections.ArrayList]@() instead of the basic @() array since it is more efficient - $null = $Result.Add($tmp) doesn't re-write the entire $Result array object like $Result += $tmp does.
Robert says
@douglas Can you post your copy here.. I would also like to exclude not responding hosts.