Windows USB WMI Scripting using VBScript

I’m looking to release one more Windows WMI Script for getting USB information from a Windows PC.

I don’t recall where I first got this script or what specific problem I was trying to solve but this Window WMI VBScript loops through all the USB devices on a PC.

I’ve modified this script a bit to look for something called “SymbolicName” and fire off a message when that value is found. This was something I must have been troubleshooting with respect to USB devices working or not and if drivers are properly installed.

WMI VBScript

' Get the serial number of a usb device

'USB_REGKEY sets the regkey where displays are found. Don't change except for debugging
'I only change it when I am looking at a .REG file that someone sent me saying that the
'code doesn't work.
Const USB_REGKEY="HKLM\SYSTEM\CurrentControlSet\Enum\USB\"
Const USB_REGKEY2="SYSTEM\CurrentControlSet\Enum\USB\"

Const DEBUGFILE="NUL"
'if set to 1 then output debug info to DEBUGFILE (also writes debug to screen if running under cscript.exe)
Const DEBUGMODE=0

'simple function to provide a wmi registry provider
'to all the other registry functions (regenumkeys, reggetstringvalue, etc...)
Function GetWMIRegProvider()
	strComputer = "."
	Set GetWMIRegProvider=GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\default:StdRegProv")
End Function

'if debugmode=1 the writes dubug info to the specified
'file and if running under cscript also writes it to screen.
Sub DebugOut(strDebugInfo)
	if DEBUGMODE=0 then
		exit sub
	end if

	strCurrScriptHost=lcase(right(wscript.fullname,len(wscript.fullname)-len(wscript.path)-1))
	
	if strCurrScriptHost="cscript.exe" then 
		wscript.echo "Debug: " & strDebugInfo
		AppendFileMode=8
		set objDebugFSO=CreateObject("Scripting.FileSystemObject")
		set objDebugStream=objDebugFSO.OpenTextFile(DEBUGFILE,AppendFileMode,True,False)
		objDebugStream.writeline strDebugInfo
		objDebugStream.Close
		set objDebugStream=Nothing
		set objDebugFSO=Nothing
	end if
End Sub 

'function to parse the specified hive
'from the registry functions above
'to all the other registry functions (regenumkeys, reggetstringvalue, etc...)
Function SetHive(RegKey)
	HKEY_CLASSES_ROOT=&H80000000
	HKEY_CURRENT_USER=&H80000001
	HKEY_CURRENT_CONFIG=&H80000005
	HKEY_LOCAL_MACHINE=&H80000002
	HKEY_USERS=&H80000003
	strHive=left(RegKey,instr(RegKey,"\"))
	if strHive="HKCR\" or strHive="HKR\" then
		SetHive=HKEY_CLASSES_ROOT
	end if
	if strHive="HKCU\" then
		SetHive=HKEY_CURRENT_USER
	end if
	if strHive="HKCC\" then
		SetHive=HKEY_CURRENT_CONFIG
	end if
	if strHive="HKLM\" then
		SetHive=HKEY_LOCAL_MACHINE
	end if
	if strHive="HKU\" then
		SetHive=HKEY_USERS
	end if
End Function


'simple function to provide an
'easier interface to the wmi registry functions
Function RegEnumKeys(RegKey)
	hive=SetHive(RegKey)
	set objReg=GetWMIRegProvider()
	strKeyPath = right(RegKey,len(RegKey)-instr(RegKey,"\"))
	objReg.EnumKey Hive, strKeyPath, arrSubKeys
	RegEnumKeys=arrSubKeys
End Function

'This function returns an array of all subkeys of the 
'regkey defined by DISPLAY_REGKEY
'(typically this should be "HKLM\SYSTEM\CurrentControlSet\Enum\USB")
Function GetAllUSBDevicesInReg()
	dim arrResult()
	redim arrResult(0)
	dim arrResult2()
	redim arrResult2(0)	
	dim arrResult3()
	redim arrResult3(0)		
	intArrResultIndex=-1
	intArrResultIndex2=-1
	intArrResultIndex3=-1
	
	arrtmpkeys=RegEnumKeys(USB_REGKEY)
	
	
	if vartype(arrtmpkeys)<>8204 then
		arrResult(0)="{ERROR}"
		GetAllUSBDevicesInReg=false
		debugout "Display=Can't enum subkeys of display regkey"
	else
		for tmpctr=0 to ubound(arrtmpkeys)
			arrtmpkeys2 = RegEnumKeys(USB_REGKEY& arrtmpkeys(tmpctr))
			
			for tmpctr2 = 0 to ubound(arrtmpkeys2)
				arrtmpkeys3 = RegEnumKeys(USB_REGKEY& arrtmpkeys(tmpctr) & "\" & arrtmpkeys2(tmpctr2))
				intArrResultIndex=intArrResultIndex+1
				redim preserve arrResult(intArrResultIndex)
				arrResult(intArrResultIndex)=USB_REGKEY & arrtmpkeys(tmpctr) & "\" & arrtmpkeys2(tmpctr2)
				debugout "USB=" & arrResult(intArrResultIndex)
				'WScript.Echo "From #1 USB=" & arrResult(intArrResultIndex)
				
				for tmpctr3 = 0 to ubound(arrtmpkeys3)
					intArrResultIndex2=intArrResultIndex2+1
					redim preserve arrResult2(intArrResultIndex2)
					arrResult2(intArrResultIndex2)=USB_REGKEY & arrtmpkeys(tmpctr) & "\" & arrtmpkeys2(tmpctr2) & "\" & arrtmpkeys3(tmpctr3)
					debugout "USB=" & arrResult2(intArrResultIndex2)
					'WScript.Echo "From #2 USB=" & arrResult2(intArrResultIndex2)
					if InStr(arrResult2(intArrResultIndex2),"Device Parameters") > 0 then
						WScript.Echo arrResult2(intArrResultIndex2)
						'WScript.Echo arrtmpkeys(tmpctr) & "\" & arrtmpkeys2(tmpctr2) & "\" & arrtmpkeys3(tmpctr3)
						GetRegValues(arrtmpkeys(tmpctr) & "\" & arrtmpkeys2(tmpctr2) & "\" & arrtmpkeys3(tmpctr3))
					end if
								
					'for tmpctr4 = 0 to ubound(arrtmpkeys4)
					'	intArrResultIndex3=intArrResultIndex3+1
					'	redim preserve arrResult3(intArrResultIndex3)
					'	arrResult2(intArrResultIndex2)=USB_REGKEY & arrtmpkeys(tmpctr) & "\" & arrtmpkeys2(tmpctr2) & "\" & arrtmpkeys3(tmpctr3)
					'	debugout "USB=" & arrResult2(intArrResultIndex2)
					'	WScript.Echo "From #2 USB=" & arrResult2(intArrResultIndex2)
					'next				
				next
			next 
		next
	end if
	GetAllUSBDevicesInReg=arrResult
End Function



' Constants (taken from WinReg.h)
'
Sub GetRegValues(strKeyPath)
const HKLM = &H80000002

dim keyPath
keyPath = "SYSTEM\CurrentControlSet\Enum\USB\" & strKeyPath

dim reg

dim valueNames, types
dim value
dim i

  set reg = getObject( "Winmgmts:root\default:StdRegProv" )

  if reg.enumValues( HKLM, keyPath, valueNames, types ) = 0 then
    if isArray( valueNames ) then
      for i = 0 to UBound( valueNames )
        reg.getStringValue HKLM, keyPath, valueNames(i), value
		If InStr(ValueNames(i),"SymbolicName") > 0 then
			msgBox("I found you! " & valueNames(i) & "=" & value )
		end if
      next
    end if
  end if

End Sub



GetAllUSBDevicesInReg

Here is a screenshot of the code on line 160. If we see a value that has the text “SymbolicName”, the script will stop and display that value in a message box.

List all USB Devices on a Window PC using VBScript

I’m going through some old scripts I’ve written or stolen from my years as a solutions engineer / developer and have come across one I thought was worthy of sharing.

The intent of this script was to loop through a list of USB devices found on a given PC.

I might store the results in a database as part of an device tracking inventory system or use the data to do something else in the code logic if I had found a specific USB device attached.

Example: VBScript to List all USB Devices

Get the code here on GitHub

'http://blogs.technet.com/b/heyscriptingguy/archive/2005/03/15/how-can-i-determine-which-usb-devices-are-connected-to-a-computer.aspx
'Win32_PnPEntity info here: http://msdn.microsoft.com/en-us/library/aa394353(v=vs.85).aspx 
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 & ": " & objUSBDevice.Manufacturer
		
    Next    
Next

If you run this script on a remote computer on a network domain instead of your own, you will probably have to run this script with Administrator rights depending on the who the network is configured.

You can check out my article on how to run VBScript as an administrator if you need help with that.

Hope this helps somebody! 🙂

~Cyber Abyss