Automation scales Operations, that is a phrase that I have used several times today in various conversations with colleagues and customers. I truly believe organizations can scale more efficiently and consistently when leveraging Automation and not be afraid of it or worse, attempting to avoid it at all cost!
In fact, Automation is a super power when it comes to the various reporting and auditing needs of an organization such as this recent inquiry in auditing all vSphere VMs that have been configured with a USB controller. The following PowerCLI snippet leverages the vSphere API to check whether there are any VMs that have been configured with either a USB 2.x controller (VirtualUSBController) or USB 3.x controller (VirtualUSBXHCIController) and outputs that in a simple table format, as shown in the example below.
# Retrieve all VMs and only include Name and Device data $vms = Get-View -ViewType VirtualMachine -Property Name,Config.Hardware.Device $results = @() foreach ($vm in $vms) { $haveUSB2Controller = $false $haveUSB3Controller = $false # Filter out devices that have USB 2.x and 3.x controllers & USB Devices (for mapping purposes) $devices = $vm.Config.Hardware.Device | where {$_.getType().Name -eq "VirtualUSBController" -or $_.getType().Name -eq "VirtualUSBXHCIController" -or $_.getType().Name -eq "VirtualUSB"} $usb2devices = @() $usb3devices = @() foreach ($device in $devices) { # Check whether USB controller is 2.x if($device.getType().Name -eq "VirtualUSBController") { $haveUSB2Controller = $true # Collect any connected USB devices on this controller foreach ($deviceKey in $device.device) { $usbDevice = $devices | where {$_.key -eq $deviceKey} $usbVid = [String]::Format("{0:x}", $usbDevice.Vendor) $usbPid = [String]::Format("{0:x}", $usbDevice.Product) $usb2devices += "${usbVid}:${usbPid}" } } # Check whether USB controller is 3.x if($device.getType().Name -eq "VirtualUSBXHCIController") { $haveUSB3Controller = $true # Collect any connected USB devices on this controller foreach ($deviceKey in $device.device) { $usbDevice = $devices | where {$_.key -eq $deviceKey} $usbVid = [String]::Format("{0:x}", $usbDevice.Vendor) $usbPid = [String]::Format("{0:x}", $usbDevice.Product) $usb3devices += "${usbVid}:${usbPid}" } } } # Only output VMs that have USB controllers if($haveUSB2Controller -or $haveUSB3Controller) { $tmp = [pscustomobject] @{ VM = $vm.Name USB2Controller = $haveUSB2Controller USB2Devices = $usb2devices USB3Controller = $haveUSB3Controller USB3Devices = $usb3devices } $results+=$tmp } } # Format output (can easily output to CSV/Excel) $results | ft
Here is an example screenshot listing only the VMs that have a USB controller and you can easily pipe the output to CSV or Excel for further processing rather than displaying the results in the console.
UPDATE (03/11/24) - The script above has been updated to also included all connected USB devices for either USB 2.x or 3.x controller found for a given VM. The format of the connected USB devices are vendorId:productId, which you can then use sites like DeviceHunt to get the friendly vendor/product name.