• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 4409
  • Last Modified:

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.
0
mpaull
Asked:
mpaull
  • 3
  • 3
1 Solution
 
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
Simplify Active Directory Administration

Administration of Active Directory does not have to be hard.  Too often what should be a simple task is made more difficult than it needs to be.The solution?  Hyena from SystemTools Software.  With ease-of-use as well as powerful importing and bulk updating capabilities.

 
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
 
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
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Keep up with what's happening at Experts Exchange!

Sign up to receive Decoded, a new monthly digest with product updates, feature release info, continuing education opportunities, and more.

  • 3
  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now