Get List of connected USB Devices

Add a reference to System.Management for your project, then try something like this:

namespace ConsoleApplication1
{
  using System;
  using System.Collections.Generic;
  using System.Management; // need to add System.Management to your project references.

  class Program
  {
    static void Main(string[] args)
    {
      var usbDevices = GetUSBDevices();

      foreach (var usbDevice in usbDevices)
      {
        Console.WriteLine("Device ID: {0}, PNP Device ID: {1}, Description: {2}",
            usbDevice.DeviceID, usbDevice.PnpDeviceID, usbDevice.Description);
      }

      Console.Read();
    }

    static List<USBDeviceInfo> GetUSBDevices()
    {
      List<USBDeviceInfo> devices = new List<USBDeviceInfo>();

      ManagementObjectCollection collection;
      using (var searcher = new ManagementObjectSearcher(@"Select * From Win32_USBHub"))
        collection = searcher.Get();      

      foreach (var device in collection)
      {
        devices.Add(new USBDeviceInfo(
        (string)device.GetPropertyValue("DeviceID"),
        (string)device.GetPropertyValue("PNPDeviceID"),
        (string)device.GetPropertyValue("Description")
        ));
      }

      collection.Dispose();
      return devices;
    }
  }

  class USBDeviceInfo
  {
    public USBDeviceInfo(string deviceID, string pnpDeviceID, string description)
    {
      this.DeviceID = deviceID;
      this.PnpDeviceID = pnpDeviceID;
      this.Description = description;
    }
    public string DeviceID { get; private set; }
    public string PnpDeviceID { get; private set; }
    public string Description { get; private set; }
  }
}

I know I'm replying to an old question, but I just went through this same exercise and found out a bit more information, that I think will contribute a lot to the discussion and help out anyone else who finds this question and sees where the existing answers fall short.

The accepted answer is close, and can be corrected using Nedko's comment to it. A more detailed understanding of the WMI Classes involved helps complete the picture.

Win32_USBHub returns only USB Hubs. That seems obvious in hindsight but the discussion above misses it. It does not include all possible USB devices, only those which can (in theory, at least) act as a hub for additional devices. It misses some devices that are not hubs (particularly parts of composite devices).

Win32_PnPEntity does include all the USB devices, and hundreds more non-USB devices. Russel Gantman's advice to use a WHERE clause search Win32_PnPEntity for a DeviceID beginning with "USB%" to filter the list is helpful but slightly incomplete; it misses bluetooth devices, some printers/print servers, and HID-compliant mice and keyboards. I have seen "USB\%", "USBSTOR\%", "USBPRINT\%", "BTH\%", "SWD\%", and "HID\%". Win32_PnPEntity is, however, a good "master" reference to look up information once you are in possession of the PNPDeviceID from other sources.

What I found was the best way to enumerate USB devices was to query Win32_USBControllerDevice. While it doesn't give detailed information for the devices, it does completely enumerate your USB devices and gives you an Antecedent/Dependent pair of PNPDeviceIDs for every USB Device (including Hubs, non-Hub devices, and HID-compliant devices) on your system. Each Dependent returned from the query will be a USB Device. The Antecedent will be the Controller it is assigned to, one of the USB Controllers returned by querying Win32_USBController.

As a bonus, it appears that under the hood, WMI walks the Device Tree when responding to the Win32_USBControllerDevice query, so the order in which these results are returned can help identify parent/child relationships. (This is not documented and is thus only a guess; use the SetupDi API's CM_Get_Parent (or Child + Sibling) for definitive results.) As an option to the SetupDi API, it appears that for all the devices listed under Win32_USBHub they can be looked up in the registry (at HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ + PNPDeviceID) and will have a parameter ParentIdPrefix which will be the prefix of the last field in the PNPDeviceID of its children, so this could also be used in a wildcard match to filter the Win32_PnPEntity query.

In my application, I did the following:

  • (Optional) Queried Win32_PnPEntity and stored the results in a key-value map (with PNPDeviceID as the key) for later retrieval. This is optional if you want to do individual queries later.
  • Queried Win32_USBControllerDevice for a definitive list of USB devices on my system (all the Dependents) and extracted the PNPDeviceIDs of these. I went further, based on order following the device tree, to assign devices to the root hub (the first device returned, rather than the controller) and built a tree based on the parentIdPrefix. The order the query returns, which matches device tree enumeration via SetupDi, is each root hub (for whom the Antecedent identifies the controller), followed by an iteration of devices under it, e.g., on my system:
    • Root hub of first controller
    • Root hub of second controller
      • First hub under root hub of second controller (has parentIdPrefix)
        • First composite device under first hub under root hub of second controller (PNPDeviceID matches above hub's ParentIdPrefix; has its own ParentIdPrefix)
          • HID Device part of the composite device (PNPDeviceID matches above composite device's ParentIDPrefix)
        • Second device under first hub under root hub of second controller
          • HID Device part of the composite device
      • Second hub under root hub of second controller
        • First device under second hub under root hub of second controller
      • Third hub under root hub of second controller
      • etc.
  • Queried Win32_USBController. This gave me the detailed information of the PNPDeviceIDs of my controllers which are at the top of the device tree (which were the Antecedents of the previous query). Using the tree derived in the previous step, recursively iterated over its children (the root hubs) and their children (the other hubs) and their children (non-hub devices and composite devices) and their children, etc.
    • Retrieved details for each device in my tree by referencing the map stored in the first step. (Optionally, one could skip the first step, and query Win32_PnPEntity individually using the PNPDeviceId to get the information at this step; probably a cpu vs. memory tradeoff determining which order is better.)

In summary, Win32USBControllerDevice Dependents are a complete list of USB Devices on a system (other than the Controllers themselves, which are the Antecedents in that same query), and by cross-referencing these PNPDeviceId pairs with information from the registry and from the other queries mentioned, a detailed picture can be constructed.


To see the devices I was interested in, I had replace Win32_USBHub by Win32_PnPEntity in Adel Hazzah's code, based on this post. This works for me:

namespace ConsoleApplication1
{
  using System;
  using System.Collections.Generic;
  using System.Management; // need to add System.Management to your project references.

  class Program
  {
    static void Main(string[] args)
    {
      var usbDevices = GetUSBDevices();

      foreach (var usbDevice in usbDevices)
      {
        Console.WriteLine("Device ID: {0}, PNP Device ID: {1}, Description: {2}",
            usbDevice.DeviceID, usbDevice.PnpDeviceID, usbDevice.Description);
      }

      Console.Read();
    }

    static List<USBDeviceInfo> GetUSBDevices()
    {
      List<USBDeviceInfo> devices = new List<USBDeviceInfo>();

      ManagementObjectCollection collection;
      using (var searcher = new ManagementObjectSearcher(@"Select * From Win32_PnPEntity"))
        collection = searcher.Get();      

      foreach (var device in collection)
      {
        devices.Add(new USBDeviceInfo(
        (string)device.GetPropertyValue("DeviceID"),
        (string)device.GetPropertyValue("PNPDeviceID"),
        (string)device.GetPropertyValue("Description")
        ));
      }

      collection.Dispose();
      return devices;
    }
  }

  class USBDeviceInfo
  {
    public USBDeviceInfo(string deviceID, string pnpDeviceID, string description)
    {
      this.DeviceID = deviceID;
      this.PnpDeviceID = pnpDeviceID;
      this.Description = description;
    }
    public string DeviceID { get; private set; }
    public string PnpDeviceID { get; private set; }
    public string Description { get; private set; }
  }
}

Adel Hazzah's answer gives working code, Daniel Widdis's and Nedko's comments mention that you need to query Win32_USBControllerDevice and use its Dependent property, and Daniel's answer gives a lot of detail without code.

Here's a synthesis of the above discussion to provide working code that lists the directly accessible PNP device properties of all connected USB devices:

using System;
using System.Collections.Generic;
using System.Management; // reference required

namespace cSharpUtilities
{
    class UsbBrowser
    {

        public static void PrintUsbDevices()
        {
            IList<ManagementBaseObject> usbDevices = GetUsbDevices();

            foreach (ManagementBaseObject usbDevice in usbDevices)
            {
                Console.WriteLine("----- DEVICE -----");
                foreach (var property in usbDevice.Properties)
                {
                    Console.WriteLine(string.Format("{0}: {1}", property.Name, property.Value));
                }
                Console.WriteLine("------------------");
            }
        }

        public static IList<ManagementBaseObject> GetUsbDevices()
        {
            IList<string> usbDeviceAddresses = LookUpUsbDeviceAddresses();

            List<ManagementBaseObject> usbDevices = new List<ManagementBaseObject>();

            foreach (string usbDeviceAddress in usbDeviceAddresses)
            {
                // query MI for the PNP device info
                // address must be escaped to be used in the query; luckily, the form we extracted previously is already escaped
                ManagementObjectCollection curMoc = QueryMi("Select * from Win32_PnPEntity where PNPDeviceID = " + usbDeviceAddress);
                foreach (ManagementBaseObject device in curMoc)
                {
                    usbDevices.Add(device);
                }
            }

            return usbDevices;
        }

        public static IList<string> LookUpUsbDeviceAddresses()
        {
            // this query gets the addressing information for connected USB devices
            ManagementObjectCollection usbDeviceAddressInfo = QueryMi(@"Select * from Win32_USBControllerDevice");

            List<string> usbDeviceAddresses = new List<string>();

            foreach(var device in usbDeviceAddressInfo)
            {
                string curPnpAddress = (string)device.GetPropertyValue("Dependent");
                // split out the address portion of the data; note that this includes escaped backslashes and quotes
                curPnpAddress = curPnpAddress.Split(new String[] { "DeviceID=" }, 2, StringSplitOptions.None)[1];

                usbDeviceAddresses.Add(curPnpAddress);
            }

            return usbDeviceAddresses;
        }

        // run a query against Windows Management Infrastructure (MI) and return the resulting collection
        public static ManagementObjectCollection QueryMi(string query)
        {
            ManagementObjectSearcher managementObjectSearcher = new ManagementObjectSearcher(query);
            ManagementObjectCollection result = managementObjectSearcher.Get();

            managementObjectSearcher.Dispose();
            return result;
        }

    }

}

You'll need to add exception handling if you want it. Consult Daniel's answer if you want to figure out the device tree and such.


If you change the ManagementObjectSearcher to the following:

ManagementObjectSearcher searcher = 
       new ManagementObjectSearcher("root\\CIMV2", 
       @"SELECT * FROM Win32_PnPEntity where DeviceID Like ""USB%"""); 

So the "GetUSBDevices() looks like this"

static List<USBDeviceInfo> GetUSBDevices()
{
  List<USBDeviceInfo> devices = new List<USBDeviceInfo>();

  ManagementObjectCollection collection;
  using (var searcher = new ManagementObjectSearcher(@"SELECT * FROM Win32_PnPEntity where DeviceID Like ""USB%"""))
    collection = searcher.Get();      

  foreach (var device in collection)
  {
    devices.Add(new USBDeviceInfo(
    (string)device.GetPropertyValue("DeviceID"),
    (string)device.GetPropertyValue("PNPDeviceID"),
    (string)device.GetPropertyValue("Description")
    ));
  }

  collection.Dispose();
  return devices;
}

}

Your results will be limited to USB devices (as opposed to all types on your system)


Comments

  1. D'Angelo

    • 2018/6/9

    Add a reference to System.Management for your project, then try something like this: namespace ConsoleApplication1 { using System; 

  2. Pedro

    • 2019/5/18

    static List<USBDeviceInfo> GetUSBDevices() { List<USBDeviceInfo> devices = new List<USBDeviceInfo>(); ManagementObjectCollection collection; using (var searcher = new ManagementObjectSearcher(@"SELECT * FROM Win32_PnPEntity where DeviceID Like ""USB%""")) collection = searcher.Get(); foreach (var device in collection) { devices.Add(new USBDeviceInfo( (string)device.GetPropertyValue("DeviceID"), (string)device.GetPropertyValue("PNPDeviceID"), (string)device.GetPropertyValue("Description

  3. Zayd

    • 2020/3/15

    Launch PowerShell or Windows Terminal with the 'PowerShell' profile. Either of those will do the job for you. · Enter the following command: Get- 

  4. Sergio

    • 2019/4/30

    Find and List Connected USB Devices in Windows 10 Launch PowerShell or Windows Terminal with the ' PowerShell' profile. Either of those will do the job for you. Enter the following command: Get-PnpDevice -PresentOnly | Where-Object { $_.InstanceId -match '^USB' }. That command will show a list of

  5. Darius

    • 2021/1/19

    To Get List of connected USB Devices: The first step is to create a new console application. Add a reference to System.Management for your 

  6. Cash

    • 2019/7/15

    USBDriveLog is a new application by Nirsoft to display a list of all USB devices that were connected to a Windows PC in the past. One of the main uses of the application is to find out if an unauthorized device was connected to the machine, for example to copy data from the PC to the USB device. USBDriveLog is a portable program for Windows, like all Nirsoft applications.

  7. Vivaan

    • 2017/8/4

    So I think what you want is the Friendly name but not the Model name. To get the Friendly names of the USBHub devices, the WMI query "Select 

  8. Kristopher

    • 2016/8/3

    class Program { static void Main(string[] args) { var usbDevices = GetUSBDevices(); foreach (var usbDevice in usbDevices) { Console.WriteLine("Device ID: {0}, PNP Device ID: {1}, Description: {2}", usbDevice.DeviceID, usbDevice.PnpDeviceID, usbDevice.Description); } Console.Read(); } static List<USBDeviceInfo> GetUSBDevices() { List<USBDeviceInfo> devices = new List<USBDeviceInfo>(); ManagementObjectCollection collection; using (var searcher = new ManagementObjectSearcher(@"Select * From

  9. Gashi

    • 2017/9/10

    USBDeview is a small utility that lists all USB devices that currently connected to your computer, as well as all USB devices that you previously used.

  10. Brennan

    • 2017/5/22

    You can also use fdisk command to list all the USB block storage devices as follows: $ sudo fdisk -l. As you can see in the screenshot below, the connected block storage devices (including the USB devices) are listed. That’s how you list all the USB devices on Linux. Thanks for reading this article.

  11. Corey

    • 2015/1/3

    How can I get a list of all the connected USB devices on a windows computer? c# list usb · Source. This question and all comments follow the "Attribution 

  12. Tatum

    • 2020/11/25

    Just in front of this entry, you can easily see what type of USB device this is. Getting USB History With Single Powershell Command You can also get all this information by just using a single command. To do this, open powershell and type "Get-ItemProperty -Path HKLM:SYSTEMCurrentControlSetEnumUSBSTOR** | Select FriendlyName." Then press enter, and you will get the history of all USB devices that have been used on your computer.

  13. Moshe

    • 2017/10/31

    to get a visual image of what device was connected to what USB in Figure C. Clear all the other check boxes, then click Install.

  14. Nelson

    • 2020/4/7

    And please also reference the attached example code, it listed all of the usb devices in the PC, and also extracted the PID/VID/Interface information for 

Comments are closed.

Recent Posts