powershellwindows-10wmiwindows-driverwindows-hello

How to get "Capabilities" of a PnP device in PowerShell


Is there a WMI or PowerShell way to get the Capabilities of a Plug and Play device like a WebCam?

I am looking for a programmatic way to enumerate or check if a Capability value, particularly CM_DEVCAP_SECUREDDEVICE (like in image listed below) is present/applicable for a camera device or not.

enter image description here

I was able to get the property key DEVPKEY_Device_Capabilities but, per Microsoft Documentation:

The value of DEVPKEY_Device_Capabilities is a bitwise OR of the CM_DEVCAP_Xxx capability flags

which doesn't give me enough granularity to know whether that specific capability is available or not (or does it and I don't understand it? 😅).

Get-PnpDevice -PresentOnly -Class Camera | Get-PnpDeviceProperty -KeyName DEVPKEY_Device_Capabilities

InstanceId KeyName                                   Type       Data
---------- -------                                   ----       ----
USB\VID... DEVPKEY_Device_Capabilities               UInt32     164

To note, I do not know in advance whether a device in the pool of devices/cameras I have to check against definitely have it enabled (nor do I have a way to procure one), so I cannot know the value of the DEVPKEY_Device_Capabilities property in advance to compare against too.


Solution

  • The value stored as DEVPKEY_Device_Capabilities is a bitfield mapping to the capabilities defined in Cfgmgr32.h - easiest way to parse the value is to define an enum type with the [Flags()] attribute then convert the value to that:

    
    [Flags()]
    enum DeviceCapabilities {
      LOCKSUPPORTED      = 0x0001
      EJECTSUPPORTED     = 0x0002
      REMOVABLE          = 0x0004
      DOCKDEVICE         = 0x0008
      UNIQUEID           = 0x0010
      SILENTINSTALL      = 0x0020
      RAWDEVICEOK        = 0x0040
      SURPRISEREMOVALOK  = 0x0080
      HARDWAREDISABLED   = 0x0100
      NONDYNAMIC         = 0x0200
      SECUREDEVICE       = 0x0400
    }
    

    Now we can do:

    PS ~> Get-PnpDevice -Class Camera -PresentOnly |Select FriendlyName,InstanceId,@{Name='Capabilities';Expression={($_ |Get-PnpDeviceProperty -KeyName DEVPKEY_Device_Capabilities).Data -as [DeviceCapabilities]}}
    
    InstanceId FriendlyName                               Capabilities
    ---------- ------------                               ------------
    USB\VID... PC camera    REMOVABLE, SILENTINSTALL, SUPRISEREMOVALOK
    

    Note: As you may have noticed, the SECUREDEVICE capability flag shows up in the property window, but the value associated with DEVPKEY_Device_Capabilities appears to only hold the lower 8 bits - I'm afraid I don't know where Explorer gets the rest :)