In an earlier post, I have shared with you a PowerShell script I use to create a report of all VM’s running in our vCenters. In this post you can find a similar script to create a report of all ESXi hosts in our vCenters.
This script will create a report containing the following information on the ESXi host:
- Serial number
- Hostname
- vCenter name
- Datacenter name
- Cluster name
- Manufacturer
- Model
- BIOS version
- Number of physical CPU’s
- CPU type
- Number of cores per CPU
- ESXi version
- ESXi license number
- Amount of memory
- The IP address of the primary DNS server
- The IP address of the secondary DNS server
- The name of the management adapter
- The IP address of the management adapter
- The MTU size of the management adapter
- The name of the vMotion adapter
- The IP address of the vMotion adapter
- The MTU size of the vMotion adapter
- The name of the vSAN adapter
- The IP address of the vSAN adapter
- The MTU size of the vSAN management adapter
(in case you do not use vSAN, you can remove the last three objects from the script)
To use the script, you will need to update variable $ListOfvCenters.
If you want to connect to the vCenter(s) using your current credentials, just remove everything related to $Credentials.
[UPDATE] Earlier today, I ran this script for the very first time in PowerShell 7 (yes, a bit late, I know 🙂 ) and I noticed that command Get-VMHostHardware is not available in PowerShell 7. While trouble shooting this, I encountered this site: https://community.broadcom.com/vmware-cloud-foundation/discussion/get-vmhosthardware. It looks like someone is using my script and already found out about this issue. I updated this script and fixed the issue where the serial number was empty in most cases. Any other bugs…please let me know.
# Import VMware PowerCLI module
If (-not (Get-Module -Name 'VMware.PowerCLI')) {
Import-Module VMware.PowerCLI
}
# Variable declaration
$Report = New-Object System.Collections.ArrayList
$DateTime = $((Get-Date).ToString('yyyy-MM-dd_hh-mm-ss'))
# Set report output path
$OutputPath = "$env:USERPROFILE\Documents\Reports"
If ( -Not (Test-Path -Path $OutputPath)) {
New-Item -ItemType directory -Path $OutputPath
}
$Outputfile = "All-ESXi-hosts-$DateTime"
Function MyLogger {
Param(
[Parameter(Mandatory = $True)] [String] $Message,
[Parameter(Mandatory = $False)] [Boolean] $Log = $False
)
$TimeStamp = Get-Date -Format "dd-MMM-yyyy HH:mm:ss"
Write-Host -NoNewline -ForegroundColor White "[$timestamp]"
Write-Host -ForegroundColor Green " $message"
$logMessage = "[$timeStamp] $message"
If ($Log -eq $True) {
$logMessage | Out-File -Append -LiteralPath $LogFile
}
} #Function MyLogger
Function MyLoggerError {
Param(
[Parameter(Mandatory = $True)] [String] $Message,
[Parameter(Mandatory = $False)] [Boolean] $Log = $False
)
$TimeStamp = Get-Date -Format "dd-MMM-yyyy HH:mm:ss"
Write-Host -NoNewline -ForegroundColor White "[$timestamp]"
Write-Host -ForegroundColor Red -BackgroundColor Yellow " $message"
$logMessage = "[$timeStamp] $message"
If ($Log -eq $True) {
$logMessage | Out-File -Append -LiteralPath $LogFile
}
} #Function MyLoggerError
# Get credentials to use to connect to the vCenter(s)
Clear-Host
$Credentials = Get-Credential -Message "Please enter the username and password to use to connect to the vCenter(s)"
# Connect to vCenter(s)
$ListOfvCenters = (
"<FQDN/IP address of vCenter #1",
"vcenter01.yourdomain.local",
"10.10.10.50"
)
Connect-VIServer $ListOfvCenters -Credential $Credentials -ErrorAction Continue
# Get a list of all ESXi hosts running in the vCenter(s)
$ListOfVMHosts = Get-VMHost | Sort-Object Name
# Get required information for each host
$Count = $ListOfVMHosts.Count
$Counter = 1
Foreach ($VMHost in $ListOfVMHosts) {
$TestVMHostConnection = $null
$TestVMHostConnection = Get-VMHost -Name $VMHost
If ($TestVMHostConnection) {
MyLogger -Message "Processing host $VMHost [$Counter/$Count]"
#Write-Host "Processing host $VMHost.Name [$Counter/$Count]"
$HostNetwork = $VMHost | Get-VMHostNetwork
$HostNetworkvMotionAdapter = $VMHost | Get-VMHostNetworkAdapter -VMKernel | Where-Object { $_.VMotionEnabled -eq $true }
$HostNetworkManagementTrafficAdapter = $VMHost | Get-VMHostNetworkAdapter -VMKernel | Where-Object { $_.ManagementTrafficEnabled -eq $true }
$HostNetworkvSANTrafficAdapter = $VMHost | Get-VMHostNetworkAdapter -VMKernel | Where-Object { $_.VsanTrafficEnabled -eq $true }
$MemoryTotalGB = [math]::Round($VMHost.MemoryTotalGB)
$Object = [PSCustomObject]@{
SerialNumber = ($VMHost.ExtensionData.Hardware.SystemInfo.OtherIdentifyingInfo | Where-Object { $_.IdentifierType.Key -eq "ServiceTag" }).IdentifierValue # Serialnumber needs to be first for VLOOKUP to work in Excel
vCenter = $VMHost.Uid.Substring($VMHost.Uid.IndexOf('@') + 1).Split(":")[0]
DataCenter = ($VMHost | Get-Datacenter)
Cluster = $VMHost.Parent
HostName = $VMHost.Name
Manufacturer = $VMHost.Manufacturer
Model = $VMHost.Model
Bios = $VMHost.ExtensionData.Hardware.BiosInfo.BiosVersion
Processor = $VMHost.ProcessorType
CPU = $VMHost.ExtensionData.Hardware.CpuInfo.NumCpuPackages
CPUCores = $VMHost.ExtensionData.Hardware.CpuInfo.NumCpuCores
MemoryGB = $MemoryTotalGB
ESXVersion = $VMHost.ExtensionData.Summary.Config.Product.FullName
ESXLicenseKey = $VMHost.LicenseKey
DNS1 = $HostNetwork.DnsAddress[0]
DNS2 = $HostNetwork.DnsAddress[1]
Gateway = $HostNetwork.VMKernelGateway
ManagementDevice = $HostNetworkManagementTrafficAdapter.name
ManagementIP = $HostNetworkManagementTrafficAdapter.ip
ManagementMTU = $HostNetworkManagementTrafficAdapter.mtu
vMotionDevice = $HostNetworkvMotionAdapter.name
vMotionIP = $HostNetworkvMotionAdapter.ip
vMotionMTU = $HostNetworkvMotionAdapter.mtu
vSANDevice = $HostNetworkvSANTrafficAdapter.name
vSANIP = $HostNetworkvSANTrafficAdapter.ip
vSANMTU = $HostNetworkvSANTrafficAdapter.mtu
}
$Report.add($Object) | Out-Null
} Else {
MyLoggerError -Message "There was an error processing host $VMHost.Name [$Counter/$Count]"
}
$Counter++
}
$Report | Export-Csv "$Outputfile.csv" -NoTypeInformation -UseCulture
$DefaultVIServers | Disconnect-VIServer -Confirm:$false
As always, please keep in mind this script is tailored to my environment, but can be used as a template for your environment. I do not pretend to be a PowerShell guru and as such my script may not be perfect. I am open to suggestions 🙂 . If you found this script useful, I’d appreciate it if you leave a comment.
Nice Script Dennis, or should I address you as “Mr. Kool”? 🙂
What was your intention with the “My Logger” routine?
Hi Roger, Dennis will do just fine 🙂
I just noted I forgot to add the MyLogger function to the code. I use that function to show output while running the script. In this case, it shows the number of hosts to be processed. In other scripts I use this function to log the output to a text file.
Thanks for bringing this to my attention, much appreciated, code is now updated. !!