Hey, Scripting Guy! Question

Hey, Scripting Guy! Using a script, is there any way to determine whether a computer has any USB 2.0 ports?

-- RD

SpacerHey, Scripting Guy! AnswerScript Center

Hey, RD. Are you familiar with the movie Freaky Friday, where the mom and the daughter switch bodies (and roles)? Well, we have sort of a Freaky Friday kind of thing going on with this question. After all, in this column the Scripting Guys are supposed to help you. But this question actually helped one of the Scripting Guys. He had been trying - unsuccessfully - to test a USB device, and had pretty much written the thing off as a piece of junk. Upon reading your question, though, he thought to himself, “Oh, yeah: USB 1.1 and USB 2.0” As soon as he tried the device in a USB 1.1 slot - as opposed to a 2.0 slot - it worked just fine.

Hey, no one ever said this particular Scripting Guy was a genius. (Editor’s Note: I’ll vouch for that.)

So we owe you one, RD; how can we ever repay you? Good point: maybe we could start by answering your question. OK, here’s a script that will probably return the number of USB 2.0 ports on a computer. Let’s show you the code, then we’ll explain why we said it will “probably” return the number of ports:

strComputer = "."
i = 0

Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colControllers = objWMIService.ExecQuery _
    ("Select * From Win32_USBController")

For Each objController in colControllers
    If Instr(objController.Name, "Enhanced") Then
        i = i + 1
    End If
Next

Wscript.Echo "No. of USB 2.0 Ports: " & i

This script starts out by assigning values to two variables. The variable strComputer is assigned the value dot (.), which - in WMI-speak - represents the local computer. Meanwhile, the counter variable i is assigned the value 0; we’ll be using this variable to keep a running tally of all the USB 2.0 ports we find.

After connecting to the WMI service we then use this query to return all the instances of the Win32_USBController class:

Set colControllers = objWMIService.ExecQuery _
    ("Select * From Win32_USBController")

From there we set up a For Each loop to walk through each item in the collection (the collection, of course, represents all the USB ports on the computer). Unfortunately, the Win32_USBController class doesn’t have a property (something like, say, Version) that can tell us the USB version; in fact, there’s no obvious way to look at the properties of a USB slot and know whether it’s version 1.1 or version 2.0. However, most 2.0 ports include the word Enhanced somewhere in their name. We can’t guarantee that all of them do, which is why we say that this script will probably return the number of USB 2.0 ports on a computer. In a few random tests around the office, however, this approach seemed to work just fine; any time we found a 2.0 slot it had a name similar to this:

VIA USB Enhanced Host Controller

So how does that help us? Well, that means we can use the InStr function to see whether the word Enhanced appears anywhere in the Name of each slot:

If Instr(objController.Name, "Enhanced") Then

If InStr returns the value True (technically, if it returns a value greater than 0), that means the word Enhanced was found somewhere in the name. In that case we increment the value of i by 1:

i = i + 1

And what if InStr returns a 0, meaning that the word Enhanced could not be found? Well, in that case we simply loop around and try the next item in the collection, leaving the value of i as-is.

We continue along these lines, incrementing i each time we find a USB slot with the word Enhanced in its name. When we’re all done we simply echo back the value of i, which tells us the number of USB 2.0 ports on the computer.

It’s not necessarily a foolproof approach, but it seems to work. And besides, it’s not like you ever did anything for us, you know.

Oh, right; we forgot about that. Um, you like chocolate by any chance?