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.
mpaullAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

mpaullAuthor Commented:
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
0
prashanthdCommented:
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

0
mpaullAuthor Commented:
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?
0
Creating Active Directory Users from a Text File

If your organization has a need to mass-create AD user accounts, watch this video to see how its done without the need for scripting or other unnecessary complexities.

Chris DentPowerShell DeveloperCommented:
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

0
mpaullAuthor Commented:
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,
0
Chris DentPowerShell DeveloperCommented:
Heavily commented version, please let me know if you need more.

In the example above, we take that PNPDeviceID (directly from Win32_PNPEntity), then do this to it (the -Replace part):

USBSTOR\\DISK&VEN_GENERIC&PROD_FLASH_DISK&REV_5.00\\CCBB1108300705542513401505&0

Which allows us to execute this query:

Get-WmiObject Win32_PNPEntity -Filter "PNPDeviceID='USBSTOR\\DISK&VEN_GENERIC&PROD_FLASH_DISK&REV_5.00\\CCBB1108300705542513401505&0'"

That one is a bit special because \ is an escape character in WQL and we must escape the escape character.

A lot of the terms, and queries, I've used here are explained here:

http://msdn.microsoft.com/en-us/library/windows/desktop/aa394606%28v=vs.85%29.aspx

But that shouldn't stop you asking for clarification here if necessary.

Cheers,

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

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

  # Test the parameter sets to construct an initial WQL Filter to send to WMI

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

  # Search the Win32_LogicalDisk class above so we can pull the partition ID out

  Get-WmiObject Win32_LogicalDisk -Filter $Filter | ForEach-Object {

    # Take the partition ID, links through Win32_LogicalDiskToPartition to Win32_DiskPartition
    # this class does nothing more than provide links between Win32_LogicalDisk and Win32_DiskPartition and
    # returns object data from Win32_DiskPartition.
    #
    # In short, this gives us the Physical Disk index based on the Logical Disk drive letter.

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

    # Use the (physical) Disk Index listed for this Partition to pick up the PhysicalDisk description

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

    # Pull out PNP Device details from Win32_PNPEntity using the PNPDeviceID listed for the Physical Disk
    # PNPDeviceID has to be cleaned up a little for the query, each \ needs to double up (e.g. \ becomes \\),
    # made slightly arcane as -Replace expects a regular expression.

    $PNPDevice = Get-WmiObject Win32_PNPEntity -Filter ("PNPDeviceID='$($PhysicalDisk.PNPDeviceID)'" -Replace '\\', '\\')

    # Find out the USB controller the device is attached to. As with matching logical drives to partitions we 
    # must traverse a linking class, this time Win32_USBControllerDevice.
    #
    # This returns data from Win32_USBController, a level above the disk (if you consider how things are plugged in)


    $USBController = Get-WmiObject -Query "ASSOCIATORS OF {$($PNPDevice.__RELPATH)} WHERE AssocClass = Win32_USBControllerDevice" | Select-Object * -Exclude __*

    # Finally, dump everything we found back to the console. Some of this will be useful, some will not. 
    # Once we have an idea what is a neater return can be crafted.

    # LogicalDisk - Select-Object * because it auto-formats (trims down) the return value otherwise.
    $_ | Select-Object *

    # Physical Disk
    $PhysicalDisk

    # USB Controller
    $USBController

  }
}

Get-USBStorage "G:"

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Chris DentPowerShell DeveloperCommented:
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
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Powershell

From novice to tech pro — start learning today.