6

I've seen articles in C# and some other languages that explain how to achieve what I'm looking for but I don't know how to convert them.

Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992
resolver101
  • 2,155
  • 11
  • 41
  • 53

6 Answers6

9

Try:

gwmi win32_diskdrive | ?{$_.interfacetype -eq "USB"} | %{gwmi -Query "ASSOCIATORS OF {Win32_DiskDrive.DeviceID=`"$($_.DeviceID.replace('\','\\'))`"} WHERE AssocClass = Win32_DiskDriveToDiskPartition"} |  %{gwmi -Query "ASSOCIATORS OF {Win32_DiskPartition.DeviceID=`"$($_.DeviceID)`"} WHERE AssocClass = Win32_LogicalDiskToPartition"} | %{$_.deviceid}

Tested with one and more than one USB device plugged-in.

CB.
  • 58,865
  • 9
  • 159
  • 159
  • Thanks, just incase anyone wants the non-alias version: Get-WmiObject Win32_diskdrive | Where-Object {$_.interfacetype -eq "USB"} | ForEach-Object {Get-WmiObject -Query "ASSOCIATORS OF {Win32_DiskDrive.DeviceID=`"$($_.DeviceID.replace('\','\\'))`"} WHERE AssocClass = Win32_DiskDriveToDiskPartition"} | ForEach-Object {Get-WmiObject -Query "ASSOCIATORS OF {Win32_DiskPartition.DeviceID=`"$($_.DeviceID)`"} WHERE AssocClass = Win32_LogicalDiskToPartition"} | ForEach-Object {$_.deviceid} – resolver101 May 18 '12 at 15:38
  • Thanks for the time in writing the answer :-) – resolver101 May 18 '12 at 15:39
  • If the shell you're running in is `cmd.exe`, as it is in some shell execution subroutines of older languages, you need to escape the quotes and run like so: `powershell -noprofile "gwmi win32_diskdrive | ?{$_.interfacetype -eq \"USB\"} | %{gwmi -Query \"ASSOCIATORS OF {Win32_DiskDrive.DeviceID=`\"$($_.DeviceID.replace('\','\\'))`\"} WHERE AssocClass = Win32_DiskDriveToDiskPartition\"} | %{gwmi -Query \"ASSOCIATORS OF {Win32_DiskPartition.DeviceID=`\"$($_.DeviceID)`\"} WHERE AssocClass = Win32_LogicalDiskToPartition\"} | %{$_.deviceid}"` – ijustlovemath Dec 14 '20 at 20:35
7

I know the subject has been dropped for a while, but since it's something I come back to pretty often, I thought I'd update things a bit.

If using Windows 7 and above, a much simpler solution would be:

Get-WmiObject Win32_Volume -Filter "DriveType='2'"

And if you want to avoid magic numbers:

Get-WmiObject Win32_Volume -Filter ("DriveType={0}" -f [int][System.IO.DriveType]::Removable)

References:
https://learn.microsoft.com/en-us/previous-versions/windows/desktop/vdswmi/win32-volume
https://learn.microsoft.com/en-us/dotnet/api/system.io.drivetype

Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992
Poorkenny
  • 1,246
  • 11
  • 16
  • Note that Windows does not necessarily mount all USB volumes as DriveType 2 (Removable Disk) in Win32_Volume. USB hard drives that get mounted with disk write caching enabled will mount as DriveType 3 (Local Disk) which is what any standard controller attached volume will show up as. – Bacon Bits Dec 29 '17 at 10:37
5
get-volume | where drivetype -eq removable | foreach driveletter

volume | ? drivetype -eq removable | % driveletter
js2010
  • 23,033
  • 6
  • 64
  • 66
4

Beginning with PowerShell v3.0, Microsoft introduce the Get-Cim* commands which make this easier than the ugliness of the Get-WmiObject ASSOCIATORS query method:

Get-CimInstance -Class Win32_DiskDrive -Filter 'InterfaceType = "USB"' -KeyOnly | 
    Get-CimAssociatedInstance -ResultClassName Win32_DiskPartition -KeyOnly |
    Get-CimAssociatedInstance -ResultClassName Win32_LogicalDisk |
    Format-List *

Or:

Get-CimInstance -Class Win32_DiskDrive -Filter 'InterfaceType = "USB"' -KeyOnly |
    Get-CimAssociatedInstance -Association Win32_DiskDriveToDiskPartition -KeyOnly |
    Get-CimAssociatedInstance -Association Win32_LogicalDiskToPartition |
    Format-List *

The above commands are equivalent.

Bacon Bits
  • 30,782
  • 5
  • 59
  • 66
0
$FlashDrives = (get-volume | Where-Object drivetype -eq removable).DriveLetter


foreach($elment in $FlashDrives)
{ 
    if($null -eq $elment)
    {
    
    }
    else
    {
       $FlashDriveLetter = $elment + ":\"
       Write-Host $FlashDriveLetter
    }
}

$HardDiskDrives = (get-volume | Sort-Object -Property DriveLetter | Where-Object drivetype -eq Fixed).DriveLetter

foreach($elment in $HardDiskDrives)
{ 
    if($null -eq $elment)
    {
    
    }
    else
    {
       $HardDiskDriveLetter = $elment + ":\"
       Write-Host $HardDiskDriveLetter
    }
}
0

This gets a single USB drive letter and stores it in the variable $DRIVE. Works in Powershell 7.3.4 where Get-WmiObject doesn't and where the USB drive shows up as Fixed as it does with Get-Volume.

$DRIVE = (Get-CimInstance -Class Win32_DiskDrive -Filter 'InterfaceType = "USB"' -KeyOnly | Get-CimAssociatedInstance -ResultClassName Win32_DiskPartition -KeyOnly | Get-CimAssociatedInstance -ResultClassName Win32_LogicalDisk).DeviceID