Link to home
Start Free TrialLog in
Avatar of mpaull
mpaullFlag for United States of America

asked on

powershell command to identify the usb device id based upon drive letter or volume name

I am looking for how in Powershell 2.0 you can identify the USB device ID of thumb drive based upon the drive letter or the Volume Name of the LogicalDisk.
Avatar of mpaull
mpaull
Flag of United States of America image

ASKER

Some additional detail

LogicalDisk
DeviceID     : M:
DriveType    : 3
ProviderName :
FreeSpace    : 1130642976768
Size         : 4000776187904
VolumeName   : FreeAgent GoFlex Drive
Maps to the following USBControllerDevice - Device ID
Disk drive  disk    USBSTOR\DISK&VEN_SEAGATE&PROD_GOFLEX_DESK&REV_0D16\NA0LBNRY&0
I am still not clear about what info is required, following will list all usb drives
gwmi win32_diskdrive | ?{$_.interfacetype -eq "USB"}

Open in new window

Avatar of mpaull

ASKER

Sorry let me try to clarify, I am trying to be able to run a powershell script providing it either a volumeName or drive letter and if the device is a USB thumbdrive it will return the following infromation as it pertains to the disk:
win32_logicalDisk information
win32_diskdrive information
win32_usbcontrollerdevice information
As they each pertain to the specific, volumename or drive letter provided.

Does that provide the neccessary clarification?
Avatar of Chris Dent
Not sure what you want to see from USBControllerDevice really, it's a linking class (in the same way that Win32_LogicalDiskToPartition is), it doesn't really give you much on its own. Still, I've used it below to get to the USB Controller the device is attached to.

Return formatting is very, very rough at the moment, if you need help cleaning it up please yell; you'll need to tell me exactly what you want to see.

Chris
Function Get-USBStorage {
  [CmdLetBinding(DefaultParameterSetName = "DriveLetter")]
  Param(
    [Parameter(Position = 1, Mandatory = $True, ParameterSetName = "DriveLetter")]
    [String]$DriveLetter,

    [Parameter(Mandatory = $True, ParameterSetName = "VolumeName")]
    [String]$VolumeName
  )

  If ($PsCmdLet.ParameterSetName -eq "DriveLetter") {
    $Filter = "DeviceID LIKE '$DriveLetter%'"
  } Else {
    $Filter = "VolumeName LIKE '$VolumeName%'"
  }

  Get-WmiObject Win32_LogicalDisk -Filter $Filter | ForEach-Object {
    $Partition = Get-WmiObject -Query "ASSOCIATORS OF {Win32_LogicalDisk.DeviceID='$($_.DeviceID)'} WHERE AssocClass = Win32_LogicalDiskToPartition" | 
      Select-Object * -Exclude __*

    $PhysicalDisk = Get-WmiObject Win32_DiskDrive -Filter "Index=$($Partition.DiskIndex)" | Select-Object * -Exclude __*

    $PNPDevice = Get-WmiObject Win32_PNPEntity -Filter ("PNPDeviceID='$($PhysicalDisk.PNPDeviceID)'" -Replace '\\', '\\')
    $USBController = Get-WmiObject -Query "ASSOCIATORS OF {$($PNPDevice.__RELPATH)} WHERE AssocClass = Win32_USBControllerDevice" | Select-Object * -Exclude __*

    # Rough return

    # LogicalDisk
    $_ | Select-Object *

    # Physical Disk
    $PhysicalDisk

    # USB Controller
    $USBController

  }
}

Get-USBStorage "G:"

Open in new window

Avatar of mpaull

ASKER

Chris

This is exactly what I was looking for can you walk me through this a bit? I understand the getting and setting the parameters but the associators  has me a bit confused and how I would get a single piece of information to use it in a susequent test specifically the PNPDeviceID                 : USBSTOR\DISK&VEN_GENERIC&PROD_FLASH_DISK&REV_5.00\CCBB1108300705542513401505&0

and making sure that is a known value attached to the USB device with the letter G: or VolumeName Xvol.

Thanks,
ASKER CERTIFIED SOLUTION
Avatar of Chris Dent
Chris Dent
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Oh and regarding ASSOCIATORS OF, you may find it helps to run a few like this:

Get-WmiObject -Query "ASSOCIATORS OF {Win32_LogicalDisk.DeviceID='C:'}"

You should find it returns a number of different classes, normally we get:

Win32_Group - Holds the owner of the logical disk
Win32_Directory - Data about "C:" as a directory (folder)
Win32_QuotaSetting - A bit OS dependent, and probably all unset (0 / -1)
Win32_DiskPartition - The one we actually want
Win32_ComputerSystem - The computer which owns everything above

We tell the query to use Win32_LogicalDiskToPartition as an associated class, letting us get exactly what we want in one query rather than doing something like this:

Get-WmiObject -Query "ASSOCIATORS OF {Win32_LogicalDisk.DeviceID='C:'}" | Where-Object { $_.CreationClassName -eq 'Win32_DiskPartition' }

Both return the same, but the original is more efficient.

Chris