Reputation: 99
Because of the way Windows assigns available drive letters to mounted USBs, I need a way to tell an end-user which USB is in which slot in a 4-port USB hub. In Device Manager under USB Mass Storage Device, I see 4 entries of the form "Port_#000x.Hub_#000y". So my question: Is there any way in Powershell to get which USB (drive letter or serial) is mounted in each hub port?
This code seems to reliably identify the physical ports in use in the hub:
$Foo1 = Get-WmiObject Win32_diskdrive | Where-Object {$_.interfacetype -eq "USB"}
But although the results refer to drives as "physical", it is not 1:1 with slot usage. For instance, right now I'm using physical slots 1, 3, and 4 but the physical device references returned by this command are \.\PHYSICALDRIVE1, \.\PHYSICALDRIVE2, and \.\PHYSICALDRIVE3. On the other hand, the device manager devices under USB Mass Storage device seem to be constant references to a physical slot.
Ideally the result would be some form of reference to physical slot along with a drive letter:
Slot Drive
------------------ -----
1 D:
2 G:
3 F:
4 E:
Any ideas welcome. I also found that I can get drive letter using the deviceID returned by this command (namely \.\PHYSICALDRIVEn:):
Get-WmiObject Win32_diskdrive | Where-Object {$_.interfacetype -eq "USB"}
But there's no apparent link between that deviceID and the one returned by this command:
Get-CimInstance win32_PnPSignedDriver | where description -like 'USB Mass Storage Device'
Which if there were such a link would give me the connection I'm looking for.
Upvotes: 0
Views: 230
Reputation: 99
Here's how I did it:
#Get slots
$SlotNames = @(Get-CimInstance win32_PnPSignedDriver | where description -like 'USB Mass Storage Device' | select Location,deviceID)
#Get Physical Device Names
$USBRecords = wmic diskdrive where "DeviceID like '%PHYSICAL%' and not DeviceID like '%PHYSICALDRIVE0%'" get deviceID,PNPdeviceID| where {$_ -ne ""}| select-object -skip 1
#Get Physical device names to Drive letters
$DriveLetters = Get-WMIObject win32_diskdrive | ?{$_.interfacetype -eq "USB"} -pv disk |
%{Get-WMIObject -Query "ASSOCIATORS OF {Win32_DiskDrive.DeviceID=`"$($_.DeviceID.replace('\','\\'))`"} WHERE AssocClass = Win32_DiskDriveToDiskPartition"} |
%{Get-WMIObject -Query "ASSOCIATORS OF {Win32_DiskPartition.DeviceID=`"$($_.DeviceID)`"} WHERE AssocClass = Win32_LogicalDiskToPartition"} |
select @{n='deviceid';e={$disk.deviceid}},@{n='driveletter';e={$_.deviceid}}
Then it's a matter of matching the records up using the USB serial that appears in position 22 in the slotnames results and position 65 of the physical device name results. The above works with the caution that you need to know which port is which in the USB hub. As @Mathias R. Jessen mentions above, the slots aren't necessarily in the order you think, which you can verify yourself by running the above on a single USB mounted in various slots in the hub.
Upvotes: 0