Name that hardware

This post was triggered by the thread Retrieving ESX host hardware information in the PowerCLI community. In that thread at a certain point the NIC HW

information was missing. The solution was to use the classId, which is 0x0200 for NICs, as a filter on the HostPciDevice objects that are present under the pciDevice property in the HostHardwareInfo object.

That made me think that this would be an ideal way to list all the hardware present on a server. But to my surprise a lot of the entries are listed as “unknown”. Since the vendorId and the deviceId are known I knew that this could be improved.

When I used the following simple script on an IBM System x3650 M2 -[7947W3C]

a lot of the entries were marked unknown.

My first thought was to use the well-known PCIDatabase.com site to find the missing HW information.

But to my surprise when I used their CSV vendor/device list to resolve the vendor- and deviceIds, I got exactly the same result. So now at least we know which list VMware uses to find the information about the HW 😉

Luckily there is another list available on the The PCI ID Repository website. And bingo, with that list it was possible to retrieve all the HW information.

The script

Annotations

Line 1: Name of the ESX/ESXi server for which you want to report the HW

Line 2: The URL of the pci.ids file on the PCI ID Repository website

Line 3: The filename of file.

Line 4: The vendor- and deviceId information will be stored in this hash table.

Line 5: With this Boolean variable you can indicate if you want to download a fresh copy of the pci.ids file from the PCI ID Repository website or if you want to use the file that is in the directory from where you run this script.

Line 8-11: Simple use of the net.WebClient to download the pci.ids file. Note that if you are running the script behind a proxy you will have extend this logic to pass the proxy account and password.

Line 14-38: This part of the script reads in the pci.ids file and stores it in hash table. The hash table makes it easier to lookup the vendor- and deviceId when we run through the HostPciDevice objects.

Line 14: The script skips the comments and the blank lines

Line 15: As is noted in the comments in the pci.ids file, the entries in the file follow a convention. Lines starting with a TAB contain deviceId entries

Line 16: Lines starting with two TABs contain subdevice entries. Note that this script does not distinguish between deviceIds and subdeviceIds.

Line 29: No TABs means that the line contains a vendorId.

Line 41-50: Now the script runs through all the HostPciDevice objects and retrieves the vendor and device information from the hash table by using the vendorId and deviceId as keys into the hash table.

The result

As can be seen from the following screenshot we now get a complete overview of all the PCI HW that is present.

No more need to run dedicated agents in the COS to gather this kind of report.

And thus also ideal for the ESXi servers !

9 Comments

    Chakrit

    Brilliant Script! Though the long output comes out as “…”. I’m not sure how to expand this as I just redirect the output “>” to a .txt file. Many thanks!

      LucD

      Thanks.
      The default view cuts of some properties to make them all fit on a console line (typically 80 chars).
      And since the “>” operator redirects the console output, you will see the same in your file
      Use the Out-File cmdlet instead. Like this (last line of the script)
      } | Out-File "C:\HW.txt"

      And if you want columns that have less blanks between them, you can use the -AutoSize parameter of the Format-Table cmdlet.
      Like this
      } | ft -AutoSize | Out-File "C:\hw.txt"

    Matt B.

    @LucD
    Hi Luc. I installed v2 RTM and tried again. I got the following message repeatedly but I did get some output. The 3 columns that did appear were Slot, Device and Vendor. Device was blank. Thanks for troubleshooting this with me. Please let me know if I need to check anything else.

    You cannot call a method on a null-valued expression.
    At C:\Program Files\VMware\Infrastructure\vSphere PowerCLI\Scripts\NameThatHardware.ps1:48 char:63
    + Device = else{$strDeviceId}}
    + CategoryInfo : InvalidOperation: (ContainsKey:String) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull

    Slot Device
    —- ——
    00:00.0
    00:01.0

    I then switched out lines 45-49 with yours and got these messages.
    You cannot call a method on a null-valued expression.
    At C:\Program Files\VMware\Infrastructure\vSphere PowerCLI\Scripts\NameThatHardware.ps1:48 char:67
    + $row.Device = else{$strDeviceId}}
    + CategoryInfo : InvalidOperation: (ContainsKey:String) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull

    Slot Vendor Device
    —- —— ——
    00:00.0 0x10DE
    00:01.0 0x10DE

      LucD

      Hi Matt,
      Did you copy the code with the 2nd icon at the top right ?
      These icons appear when you hover over the box that contains the code.

      From the error message it looks as if the code is not complete for that statement.
      Luc.

    Matt B.

    This script is exactly what I need. For those of us new to PowerCLI, how do I properly run this? I have installed the PowerCli, ran Set-ExecutionPolicy RemoteSigned once, used connect-viserver to connect to the ESX server, changed line 1 of the script to the ESX server name and ran the script as “name that hardware.ps1”. I get the following error repeatedly.

    + New-Object PSObject -Property <<<< @{
    You cannot call a method on a null-valued expression.
    At C:\Program Files\VMware\Infrastructure\vSphere PowerCLI\Scripts\name that hardware.ps1:48 char:63
    + Device = else{$strDeviceId}}
    New-Object : A parameter cannot be found that matches parameter name 'Property'.
    At C:\Program Files\VMware\Infrastructure\vSphere PowerCLI\Scripts\name that hardware.ps1:45 char:31

      LucD

      Hi Matt. It looks as if you’re not running PowerShell v2 RTM.
      You can use the script in Tobias’s post called Are you using the correct PowerShell version? to check what version you are running.

      If for whatever reason you can’t upgrade to PowerShell v2 RTM change lines 45-49 like this

      $row = "" | Select Slot, Vendor, Device
      $row.Slot = $_.Id
      $row.Vendor = &{if($deviceTab.ContainsKey($strVendorId)){$deviceTab[$strVendorId].Vendor}else{$strVendorId}}
      $row.Device = &{if($deviceTab[$strVendorId].deviceTab.ContainsKey($strDeviceId)){$deviceTab[$strVendorId].deviceTab[$strDeviceId]}else{$strDeviceId}}
      $row

    Alan Renouf

    Brilliant stuff, if only I had this 3 weeks ago when the damn order monkeys couldnt remember what model of nic they ordered !

    Amazing script (as always) Luc.

    michael

    cool script!
    as usual.

    Robert van den Nieuwendijk

    Awesome script. Beautiful to see how you combine information from two different sources. And I love the hash table in a hash table technique.

Leave a Reply

Your email address will not be published. Required fields are marked *

*
*

9 + nineteen =

This site uses Akismet to reduce spam. Learn how your comment data is processed.