Go code using WMI returns inconsistent USB port count; how to reliably get fixed physical USB ports?
08:21 19 Dec 2025

I'm trying to get the number of physical USB ports on a Windows machine using Go and WMI. I wrote the following code using ole and oleutil:

func GetUSBCount() (int, error) {
runtime.LockOSThread()
defer runtime.UnlockOSThread()
if err := ole.CoInitialize(0); err != nil {
    return 0, fmt.Errorf("CoInitialize failed: %v", err)
}
defer ole.CoUninitialize()

unknown, err := oleutil.CreateObject("WbemScripting.SWbemLocator")
if err != nil {
    return 0, fmt.Errorf("CreateObject failed: %v", err)
}
defer unknown.Release()

ws, err := unknown.QueryInterface(ole.IID_IDispatch)
if err != nil {
    return 0, fmt.Errorf("QueryInterface failed: %v", err)
}
defer ws.Release()

serviceRaw, err := oleutil.CallMethod(ws, "ConnectServer")
if err != nil {
    return 0, fmt.Errorf("ConnectServer failed: %v", err)
}
service := serviceRaw.ToIDispatch()
defer service.Release()

resultRaw, err := oleutil.CallMethod(service, "ExecQuery", "SELECT * FROM Win32_USBPort")
if err != nil {
    return 0, fmt.Errorf("ExecQuery failed: %v", err)
}
result := resultRaw.ToIDispatch()
defer result.Release()

countRaw, err := oleutil.GetProperty(result, "Count")
if err != nil {
    return 0, fmt.Errorf("GetProperty Count failed: %v", err)
}

count := int(countRaw.Val)
return count, nil

}

The problem:

The count returned by this code is not consistent.

Sometimes it returns 3, sometimes 4, even when I haven’t physically added or removed ports.

Connecting a USB device doesn’t reliably increase the count.

I’ve tried querying Win32_USBHub and Win32_USBPort but both approaches give unreliable results.

What I want:

A way to reliably get the number of fixed physical USB ports on a Windows machine (not counting virtual devices or hubs created by plugged-in devices).

Is there a better way to achieve this in Go (or via Windows APIs/WMI) that will give me consistent physical USB port counts?

go