Src/Private/Get-PciDeviceDetail.ps1
|
Function Get-PciDeviceDetail { <# .SYNOPSIS Helper function to return PCI Devices Drivers & Firmware information for a specific host. .PARAMETER Server vCenter VISession object. .PARAMETER esxcli Esxcli session object associated to the host. .PARAMETER VMHost VMHost object. Required for ESXi 8.x compatibility where VMkernelName is no longer populated in esxcli hardware.pci.list; used to build a PCI address to VMkernel name map. .EXAMPLE $Credentials = Get-Credential $Server = Connect-VIServer -Server vcenter01.example.com -Credentials $Credentials $VMHost = Get-VMHost -Server $Server -Name esx01.example.com $esxcli = Get-EsxCli -Server $Server -VMHost $VMHost -V2 Get-PciDeviceDetail -Server $vCenter -esxcli $esxcli -VMHost $VMHost Device : vmhba0 Model : Sunrise Point-LP AHCI Controller Driver : vmw_ahci Driver Version : 1.0.0-34vmw.650.0.14.5146846 Firmware Version : N/A VIB Name : vmw-ahci VIB Version : 1.0.0-34vmw.650.0.14.5146846 .NOTES Author: Erwan Quelin heavily based on the work of the vDocumentation team - https://github.com/arielsanchezmora/vDocumentation/blob/master/powershell/vDocumentation/Public/Get-ESXIODevice.ps1 #> [CmdletBinding()] Param ( [Parameter(Mandatory = $true)] $Server, [Parameter(Mandatory = $true)] $esxcli, [Parameter(Mandatory = $false)] $VMHost ) Begin { } Process { # Build PCI address -> VMkernel name mapping for ESXi 8 compatibility. # VMkernelName is no longer populated in esxcli hardware.pci.list on ESXi 8.x, # so we derive it from the PowerCLI API using the PCI address as the join key. $addrToVmkernel = @{} if ($null -ne $VMHost) { Get-VMHostNetworkAdapter -VMHost $VMHost -Physical | ForEach-Object { if ($_.PciId) { $addrToVmkernel[$_.PciId] = $_.DeviceName } } Get-VMHostHba -VMHost $VMHost | ForEach-Object { if ($_.Pci) { $addrToVmkernel[$_.Pci] = $_.Device } } (Get-VMHost $VMHost | Get-View -Property Config).Config.GraphicsInfo | ForEach-Object { if ($_.pciId) { $addrToVmkernel[$_.pciId] = $_.deviceName } } } $pciDevices = $esxcli.hardware.pci.list.Invoke() | Where-Object { $vmkName = if ($_.VMkernelName -match 'vmhba|vmnic|vmgfx') { $_.VMkernelName } else { $addrToVmkernel[$_.Address] } $vmkName -match 'vmhba|vmnic|vmgfx' -and $_.ModuleName -ne 'None' } $nicList = $esxcli.network.nic.list.Invoke() | Sort-Object Name foreach ($pciDevice in $pciDevices) { # Resolve VMkernel name: populated directly on ESXi < 8, address lookup required on ESXi 8+ $vmkernelName = if ($pciDevice.VMkernelName -match 'vmhba|vmnic|vmgfx') { $pciDevice.VMkernelName } else { $addrToVmkernel[$pciDevice.Address] } # Reset per-device defaults on every iteration $firmwareVersion = 'N/A' $driverVib = @{ Name = 'N/A'; Version = 'N/A' } $driverVersion = $esxcli.system.module.get.Invoke(@{module = $pciDevice.ModuleName }) | Select-Object -ExpandProperty Version # Get NIC Firmware version if (($vmkernelName -like 'vmnic*') -and ($nicList.Name -contains $vmkernelName)) { $vmnicDetail = $esxcli.network.nic.get.Invoke(@{nicname = $vmkernelName }) $firmwareVersion = $vmnicDetail.DriverInfo.FirmwareVersion # Get NIC driver VIB package version $driverVib = $esxcli.software.vib.list.Invoke() | Select-Object -Property Name, Version | Where-Object { $_.Name -eq $vmnicDetail.DriverInfo.Driver -or $_.Name -eq "net-" + $vmnicDetail.DriverInfo.Driver -or $_.Name -eq "net55-" + $vmnicDetail.DriverInfo.Driver } <# If HP Smart Array vmhba* (scsi-hpsa driver) then get Firmware version else skip if VMkernnel is vmhba*. Can't get HBA Firmware from Powercli at the moment only through SSH or using Putty Plink+PowerCli. #> } elseif ($vmkernelName -like 'vmhba*') { if ($pciDevice.DeviceName -match 'smart array') { $hpsa = $VMHost.ExtensionData.Runtime.HealthSystemRuntime.SystemHealthInfo.NumericSensorInfo | Where-Object { $_.Name -match 'HP Smart Array' } if ($hpsa) { $firmwareVersion = (($hpsa.Name -split 'firmware')[1]).Trim() } } # Get HBA driver VIB package version $vibName = $pciDevice.ModuleName -replace '_', '-' $driverVib = $esxcli.software.vib.list.Invoke() | Select-Object -Property Name, Version | Where-Object { $_.Name -eq "scsi-$vibName" -or $_.Name -eq "sata-$vibName" -or $_.Name -eq $vibName } } # Output collected data [PSCustomObject]@{ 'Device' = $vmkernelName 'Model' = $pciDevice.DeviceName 'Driver' = $pciDevice.ModuleName 'Driver Version' = $driverVersion 'Firmware Version' = $firmwareVersion 'VIB Name' = $driverVib.Name 'VIB Version' = $driverVib.Version } } } End { } } |