WilliamLam.com

  • About
    • About
    • Privacy
  • VMware Cloud Foundation
  • VKS
  • Homelab
    • Resources
    • Nested Virtualization
  • VMware Nostalgia
  • Apple
You are here: Home / Automation / Quick Tip - Audit vSphere VMs configured with USB Controllers

Quick Tip - Audit vSphere VMs configured with USB Controllers

03.07.2024 by William Lam // 6 Comments

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.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
# 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
# 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
# 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.

More from my site

  • Quick Tip - Automating cpuUniformityHardCheckPanic configuration for ESXi Kickstart with USB
  • Google Coral USB Edge TPU Accelerator on ESXi
  • USB Network Native Driver Fling for ESXi 8.0 Update 1
  • How to recover ESXi installed on USB device after disabling vmkusb module?
  • Emulating a Virtual USB storage device using Nested ESXi

Categories // Automation, PowerCLI Tags // usb

Comments

  1. *protecteduvas says

    03/08/2024 at 1:51 pm

    Hi William, thanks for sharing this!

    I put something together to remove the controllers. Not sure if this is the best method but ill share in case it helps someone else:

    # Get the goods
    $usr = $env:USERNAME + '@' + $env:USERDNSDOMAIN
    $creds = Get-Credential -Message 'Credentials with vCenter Access' -UserName $usr
    $vcsa = 'vcsaname.fqdn.com'

    # Get VM list to modify
    $ListOVms = cat c:\temp\VmList.txt

    # Let it rip
    foreach($comp in $ListOVms)
    {
    $vm = Get-VM -Name "$comp"

    $usbControllers = $vm.ExtensionData.Config.Hardware.Device | Where-Object { $_.DeviceInfo.Label -like "USB*Controller*" }
    $deviceSpecs = @()

    foreach ($usbController in $usbControllers)
    {
    $usbControllerName = $usbController.DeviceInfo.Label
    Write-Host "Removing USB controller: $usbControllerName"

    $deviceSpec = New-Object VMware.Vim.VirtualDeviceConfigSpec
    $deviceSpec.operation = "remove"
    $deviceSpec.device = $usbController

    $deviceSpecs += $deviceSpec
    }

    $spec = New-Object VMware.Vim.VirtualMachineConfigSpec
    $spec.deviceChange = $deviceSpecs
    $vm.ExtensionData.ReconfigVM_Task($spec)
    }

    Reply
    • William Lam says

      03/11/2024 at 3:48 pm

      Thanks for sharing. If you know there aren't any connected USB devices on the controller, then the code above is perfect for automating the removal. If not, you'll need to add a check before just removing the controller, especially if the USB device is in use

      Reply
    • *protectedFish says

      04/01/2024 at 11:12 am

      Caveat being the VM's need to be in a powered off state. Thanks for sharing

      Reply
  2. *protectedGreg says

    03/08/2024 at 10:12 pm

    Why?

    Would be great to get an overview of best practices around USB to complete the picture. I can see this as a security feature and vdi already offers that sort of ability to tune how USB is used in the virtual machine. I also think that there could be some performance related too. Thanks as always the articles are really coming out quite quickly these days!

    Reply
  3. *protectedTim Fitzpatrick says

    03/11/2024 at 1:10 pm

    Is there an easy way to detect if something is attached to the USB Controller that your script finds?

    Reply
    • William Lam says

      03/11/2024 at 3:49 pm

      Yup. Each controller (https://vdc-download.vmware.com/vmwb-repository/dcr-public/184bb3ba-6fa8-4574-a767-d0c96e2a38f4/ba9422ef-405c-47dd-8553-e11b619185b2/SDK/vsphere-ws/docs/ReferenceGuide/vim.vm.device.VirtualController.html) has a device array which would list the connected devices, but it only contains the device key.

      I've just updated the script snippet to also output the connected devices which are in the form of vendorId:productId. See the additional notes for details

      Reply

Thanks for the comment!Cancel reply

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

Search

Thank Author

Author

William is Distinguished Platform Engineering Architect in the VMware Cloud Foundation (VCF) Division at Broadcom. His primary focus is helping customers and partners build, run and operate a modern Private Cloud using the VMware Cloud Foundation (VCF) platform.

Connect

  • Bluesky
  • Email
  • GitHub
  • LinkedIn
  • Mastodon
  • Reddit
  • RSS
  • Twitter
  • Vimeo

Recent

  • Programmatically accessing the Broadcom Compatibility Guide (BCG) 05/06/2025
  • Quick Tip - Validating Broadcom Download Token  05/01/2025
  • Supported chipsets for the USB Network Native Driver for ESXi Fling 04/23/2025
  • vCenter Identity Federation with Authelia 04/16/2025
  • vCenter Server Identity Federation with Kanidm 04/10/2025

Advertisment

Copyright WilliamLam.com © 2025

 

Loading Comments...
 

    Privacy & Cookies: This site uses cookies. By continuing to use this website, you agree to their use.
    To find out more, including how to control cookies, see here: Cookie Policy