Displaying USB Devices using WMI

Over on MyItForum.com, I came upon a VBScript in a forum to find all the PNP entities associated with a USBController. I rewrote it in PowerShell and was pretty happy with the results so I thought I would share them. The first thing you need to understand is that the WMI class WIN32_USBControllerDevice describes the connection between USB controllers (The Antecedent) and their logical devices [CIM_LOGICALDEVICE] (the Dependent). Let me illustrate:

PS> gwmi Win32_USBControllerDevice |fl Antecedent,Dependent

Antecedent : \\JPSVISTA1\root\cimv2:Win32_USBController.DeviceID=”PCI\\VEN_
8086&DEV_2658&SUBSYS_01891028&REV_03\\3&2B8E0B4B&0&E8″
Dependent : \\JPSVISTA1\root\cimv2:Win32_PnPEntity.DeviceID=”USB\\ROOT_HUB
\\4&2F35A3CB&0″

Antecedent : \\JPSVISTA1\root\cimv2:Win32_USBController.DeviceID=”PCI\\VEN_
8086&DEV_2658&SUBSYS_01891028&REV_03\\3&2B8E0B4B&0&E8″
Dependent : \\JPSVISTA1\root\cimv2:Win32_PnPEntity.DeviceID=”USB\\VID_04FC
&PID_0003\\5&2604C4EE&0&1″

Antecedent : \\JPSVISTA1\root\cimv2:Win32_USBController.DeviceID=”PCI\\VEN_
8086&DEV_2658&SUBSYS_01891028&REV_03\\3&2B8E0B4B&0&E8″
Dependent : \\JPSVISTA1\root\cimv2:Win32_PnPEntity.DeviceID=”HID\\VID_04FC
&PID_0003\\6&185E20EC&0&0000″

Antecedent : \\JPSVISTA1\root\cimv2:Win32_USBController.DeviceID=”PCI\\VEN_
8086&DEV_2659&SUBSYS_01891028&REV_03\\3&2B8E0B4B&0&E9″
Dependent : \\JPSVISTA1\root\cimv2:Win32_PnPEntity.DeviceID=”USB\\ROOT_HUB
\\4&88AB5AD&0″

Antecedent : \\JPSVISTA1\root\cimv2:Win32_USBController.DeviceID=”PCI\\VEN_
8086&DEV_2659&SUBSYS_01891028&REV_03\\3&2B8E0B4B&0&E9″
Dependent : \\JPSVISTA1\root\cimv2:Win32_PnPEntity.DeviceID=”USB\\VID_413C
&PID_8103\\5&111B5EE1&0&1″

Antecedent : \\JPSVISTA1\root\cimv2:Win32_USBController.DeviceID=”PCI\\VEN_
8086&DEV_2659&SUBSYS_01891028&REV_03\\3&2B8E0B4B&0&E9″
Dependent : \\JPSVISTA1\root\cimv2:Win32_PnPEntity.DeviceID=”BTH\\MS_RFCOM
M\\6&3250FFA7&0&0″

Antecedent : \\JPSVISTA1\root\cimv2:Win32_USBController.DeviceID=”PCI\\VEN_
8086&DEV_2659&SUBSYS_01891028&REV_03\\3&2B8E0B4B&0&E9″
Dependent : \\JPSVISTA1\root\cimv2:Win32_PnPEntity.DeviceID=”BTH\\MS_BTHBR
B\\6&3250FFA7&0&1″

Antecedent : \\JPSVISTA1\root\cimv2:Win32_USBController.DeviceID=”PCI\\VEN_
8086&DEV_2659&SUBSYS_01891028&REV_03\\3&2B8E0B4B&0&E9″
Dependent : \\JPSVISTA1\root\cimv2:Win32_PnPEntity.DeviceID=”BTH\\MS_BTHPA
N\\6&3250FFA7&0&2″

Antecedent : \\JPSVISTA1\root\cimv2:Win32_USBController.DeviceID=”PCI\\VEN_
8086&DEV_265A&SUBSYS_01891028&REV_03\\3&2B8E0B4B&0&EA”
Dependent : \\JPSVISTA1\root\cimv2:Win32_PnPEntity.DeviceID=”USB\\ROOT_HUB
\\4&8904A15&0″

Antecedent : \\JPSVISTA1\root\cimv2:Win32_USBController.DeviceID=”PCI\\VEN_
8086&DEV_265B&SUBSYS_01891028&REV_03\\3&2B8E0B4B&0&EB”
Dependent : \\JPSVISTA1\root\cimv2:Win32_PnPEntity.DeviceID=”USB\\ROOT_HUB
\\4&2F300F63&0″

Antecedent : \\JPSVISTA1\root\cimv2:Win32_USBController.DeviceID=”PCI\\VEN_
8086&DEV_265C&SUBSYS_01891028&REV_03\\3&2B8E0B4B&0&EF”
Dependent : \\JPSVISTA1\root\cimv2:Win32_PnPEntity.DeviceID=”USB\\ROOT_HUB
20\\4&16530ED8&0″

Clear as mud right? These are WMI Path names and are not so readable. That’s ok for now; the point is that this class points to 2 other WMI entities.

Below is the VBScript that I got from here.

strComputer = “.”

Set objWMIService = GetObject(“winmgmts:\\” & strComputer & “\root\cimv2″)
Set colDevices = objWMIService.ExecQuery _
   (“Select * From Win32_USBControllerDevice”)

For Each objDevice in colDevices
   strDeviceName = objDevice.Dependent
   strQuotes = Chr(34)
   strDeviceName = Replace(strDeviceName, strQuotes, “”)
   arrDeviceNames = Split(strDeviceName, “=”)
   strDeviceName = arrDeviceNames(1)
   Set colUSBDevices = objWMIService.ExecQuery _
       (“Select * From Win32_PnPEntity Where DeviceID = ‘” & strDeviceName & “‘”)
   For Each objUSBDevice in colUSBDevices
       Wscript.Echo objUSBDevice.Description
       WScript.Echo objUSBDevice.PnPDeviceID ‘ Changed from Description to PnPDeviceID
                                 ‘as this script can be altered to return any property
                                 ‘of the Win32_USBControllerDevice collection.
   Next   
Next

This script does a query to get all instances of WIN32_USBControllerDevice, then for each one it takes the DEPENDENT property and converts it to a query, it then executes that query (which gets the PNPEntities) and formats the description and deviceID.

We don’t have to do that in PowerShell. If you have a WMIPath, you can get the object it points to just by casting it with [WMI]. So that means that you can replace this script with the following one-liner (Note: I decided to sort and things to make it prettier [and to show off J] )

 

PS> gwmi Win32_USBControllerDevice |%{[wmi]($_.Dependent)} |
>> Sort Description,DeviceID | ft Description,DeviceID -auto
>>

Description DeviceID
———– ——–
Bluetooth Device (Personal Area Network) BTH\MS_BTHPAN\6&3250FFA7&0&2
Bluetooth Device (RFCOMM Protocol TDI) BTH\MS_RFCOMM\6&3250FFA7&0&0
Dell Wireless 350 Bluetooth Module USB\VID_413C&PID_8103\5&111B5EE…
Disk drive USBSTOR\DISK&VEN_COWON&PROD_IAU…
HID-compliant consumer control device HID\VID_045E&PID_00B9&COL01\6&2…
HID-compliant mouse HID\VID_045E&PID_00B9&COL02\6&2…
HID-compliant mouse HID\VID_04FC&PID_0003\6&185E20E…
Microsoft Bluetooth Enumerator BTH\MS_BTHBRB\6&3250FFA7&0&1
USB Human Interface Device USB\VID_045E&PID_00B9\5&2616CD8…
USB Human Interface Device USB\VID_04FC&PID_0003\5&2604C4E…
USB Mass Storage Device USB\VID_0E21&PID_0600\0002F685D…
USB Root Hub USB\ROOT_HUB\4&2F300F63&0
USB Root Hub USB\ROOT_HUB\4&2F35A3CB&0
USB Root Hub USB\ROOT_HUB\4&88AB5AD&0
USB Root Hub USB\ROOT_HUB\4&8904A15&0
USB Root Hub USB\ROOT_HUB20\4&16530ED8&0

Not one to leave well enough alone, let’s guild this lilly:

PS> gwmi Win32_USBControllerDevice |%{[wmi]($_.Dependent)} |
>> Sort Manufacturer,Description,DeviceID |
>> Ft -GroupBy Manufacturer Description,Service,DeviceID
>>

Manufacturer: (Standard disk drives)

Description Service DeviceID
———– ——- ——–
Disk drive disk USBSTOR\DISK&VEN_COWO…

Manufacturer: (Standard system devices)

Description Service DeviceID
———– ——- ——–
USB Human Interface De… HidUsb USB\VID_045E&PID_00B9…
USB Human Interface De… HidUsb USB\VID_04FC&PID_0003…

Manufacturer: (Standard USB Host Controller)

Description Service DeviceID
———– ——- ——–
USB Root Hub usbhub USB\ROOT_HUB\4&2F300F…
USB Root Hub usbhub USB\ROOT_HUB\4&2F35A3…
USB Root Hub usbhub USB\ROOT_HUB\4&88AB5AD&0
USB Root Hub usbhub USB\ROOT_HUB\4&8904A15&0
USB Root Hub usbhub USB\ROOT_HUB20\4&1653…

Manufacturer: Compatible USB storage device

Description Service DeviceID
———– ——- ——–
USB Mass Storage Device USBSTOR USB\VID_0E21&PID_0600…

Manufacturer: Dell

Description Service DeviceID
———– ——- ——–
Dell Wireless 350 Blue… BTHUSB USB\VID_413C&PID_8103…

Manufacturer: Microsoft

Description Service DeviceID
———– ——- ——–
Bluetooth Device (Pers… BthPan BTH\MS_BTHPAN\6&3250F…
Bluetooth Device (RFCO… RFCOMM BTH\MS_RFCOMM\6&3250F…
HID-compliant consumer… HID\VID_045E&PID_00B9…
HID-compliant mouse mouhid HID\VID_045E&PID_00B9…
HID-compliant mouse mouhid HID\VID_04FC&PID_0003…
Microsoft Bluetooth En… BthEnum BTH\MS_BTHBRB\6&3250F…

In the past, people have thrown rocks at WMI for being difficult and obtuse. There is a ton of great information in WMI and now with PowerShell, you have a tool that makes it easy to find and manipulate. If you’ve looked at WMI in the past and given up, I encourage you to get some PowerShell skills under your belt and go at it again.

Enjoy!

Jeffrey Snover [MSFT]
Windows PowerShell/MMC Architect
Visit the Windows PowerShell Team blog at: http://blogs.msdn.com/PowerShell
Visit the Windows PowerShell ScriptCenter at: http://www.microsoft.com/technet/scriptcenter/hubs/msh.mspx