Reputation: 779
Is there a method that allows us to get its letter and physical type for each driver? That is, get one array where something like this will be:
$Drivers = *Get-Something* # Where $Drivers is @{} array
$Drivers
---
C: SSD
D: HDD
E: SSD
F: SSD
I need to bind the data of these two in an array. The first contains letters. the second contains physical types:
$DriversName = (Get-WmiObject -Class Win32_Volume).DriveLetter | Where-Object { $_ }
$DriversType = Get-PhysicalDisk | Select-Object -ExpandProperty MediaType
But I do not know which element of the first array refers to the element of the second array. Because the system does not prioritize them.
Thanks so much for the answers.
Upvotes: 2
Views: 7318
Reputation: 779
Here is the solution (thanks js2010 for the idea). Nearly. Since you need logical drives to display. Decision by Chris Dent:
powershell
Get-PhysicalDisk | ForEach-Object {
$physicalDisk = $_
$physicalDisk |
Get-Disk |
Get-Partition |
Where-Object DriveLetter |
Select-Object DriveLetter, @{n='MediaType';e={ $physicalDisk.MediaType }}
}
Upvotes: 5
Reputation: 27418
Get-Volume
returns DriveLetter and DriveType properties.
EDIT:
Get-PhysicalDisk
has the MediaType property. But its ObjectId doesn't match up with a drive letter.
$disk = get-physicaldisk
$disk | get-disk | get-partition | select DriveLetter,
@{n='MediaType';e={$disk.MediaType}}
DriveLetter MediaType
----------- ---------
C SSD
Hmm why doesn't pipevariable work? There can be multiple drive letters.
get-physicaldisk -pv disk | get-disk | get-partition | select DriveLetter,
@{n='MediaType';e={$disk.MediaType}}
DriveLetter MediaType
----------- ---------
C
Upvotes: 0
Reputation: 61013
You can use the SerialNumber
property of the disks to map the output and combine the logical drive letter with the MediaType of the physical disks.
# create a Hashtable to store the DriveLetter and SerialNumber obtained from WMI (I use Get-CimInstance here)
$ht = @{}
$wmiQuery1 = 'ASSOCIATORS OF {{Win32_DiskDrive.DeviceID="{0}"}} WHERE AssocClass = Win32_DiskDriveToDiskPartition'
$wmiQuery2 = 'ASSOCIATORS OF {{Win32_DiskPartition.DeviceID="{0}"}} WHERE AssocClass = Win32_LogicalDiskToPartition'
# for PowerShell < 3.0 use Get-WmiObject instead of Get-CimInstance
Get-CimInstance -ClassName Win32_DiskDrive | Where-Object { $_.MediaType -match '^(Fixed|External)' } |
ForEach-Object {
# store the disk serialnumber of the physical disk and get the get the partition info for each disk
$serial = $_.SerialNumber
Get-CimInstance -Query ($wmiQuery1 -f $_.DeviceID.Replace('\','\\')) #'# double-up the backslashes
} |
ForEach-Object {
# now get the logical disks on each partition to find the drive letters in property DeviceID
Get-CimInstance -Query ($wmiQuery2 -f $_.DeviceID)
} |
ForEach-Object { $ht[$_.DeviceID] = $serial } # store the drive letters as key, the disk serial as value
# get the serialnumber and mediatype for each physical disk with Get-PhysicalDisk
$disks = Get-PhysicalDisk | Select-Object SerialNumber, MediaType
# loop through the Hashtable with partition/volume info gathered before and map on the SerialNumber property
$ht.Keys | ForEach-Object {
$drive = $_
$type = ($disks | Where-Object { $_.SerialNumber -eq $ht[$drive] }).MediaType
[PsCustomObject]@{
DriveLetter = $drive
MediaType = if ($type) { $type } else { 'Unspecified' }
}
} | Sort-Object DriveLetter
The result should look like
DriveLetter MediaType ----------- --------- C: SSD D: HHD E: SSD F: SSD
Upvotes: 1
Reputation: 5072
First you want to look at Win32_LogicalDiskToPartition
.
PS C:\> Get-WMIObject Win32_LogicalDiskToPartition | Select-Object Antecedent, Dependent | Write
Which gives on my system
Antecedent Dependent
---------- ---------
\\DESKTOP-JJASNFC\root\cimv2:Win32_DiskPartition.DeviceID="Disk #1, Partition #0" \\DESKTOP-JJASNFC\root\cimv2:Win32_LogicalDisk.DeviceID="C:"
\\DESKTOP-JJASNFC\root\cimv2:Win32_DiskPartition.DeviceID="Disk #0, Partition #1" \\DESKTOP-JJASNFC\root\cimv2:Win32_LogicalDisk.DeviceID="D:"
Query Win32_LogicalDisk
to get information about the drive letter.
Get-WMIObject Win32_LogicalDisk | Select DeviceID, Path | Write
yields for me
DeviceID Path
-------- ----
C: \\DESKTOP-JJASNFC\root\cimv2:Win32_LogicalDisk.DeviceID="C:"
D: \\DESKTOP-JJASNFC\root\cimv2:Win32_LogicalDisk.DeviceID="D:"
F: \\DESKTOP-JJASNFC\root\cimv2:Win32_LogicalDisk.DeviceID="F:"
Here the Path
property is connected to the Dependent
property we saw before.
In Win32_DiskPartition
we can find the device Id
Get-WMIObject Win32_DiskPartition | Select DiskIndex, MedPath | Write
Again, for me
DiskIndex Path
--------- ----
1 \\DESKTOP-JJASNFC\root\cimv2:Win32_DiskPartition.DeviceID="Disk #1, Partition #0"
0 \\DESKTOP-JJASNFC\root\cimv2:Win32_DiskPartition.DeviceID="Disk #0, Partition #0"
0 \\DESKTOP-JJASNFC\root\cimv2:Win32_DiskPartition.DeviceID="Disk #0, Partition #1"
Now, the most interesting part for you is when we query MSFT_Physicaldisk
.
Get-WmiObject MSFT_Physicaldisk -Namespace root\Microsoft\Windows\Storage | Select DeviceId, MediaType | Write
...
DeviceId MediaType
-------- ---------
1 4
0 4
Here, MediaType
is the key. A value of 4 means SSD, 3 means HDD. DeviceId
corresponds to the DiskIndex
.
So, if you join those 4 "tables" together you can achieve what you want. My Powershell-Fu is not good enough.
To recap: The joins are like
MSFT_Physicaldisk.MediaType, MSFT_Physicaldisk.DeviceID <-->
Win32_DiskPartition.DiskIndex, *Win32_DiskPartition.Path <-->
Win32_LogicalDiskToPartition.Dependent, Win32_LogicalDiskToPartition.Antecedent <-->
Win32_LogicalDisk.Path, Win32_LogicalDisk.DeviceID
Upvotes: 3
Reputation: 1010
This is working for me:
$partitions = Get-CimInstance Win32_DiskPartition
$physDisc = get-physicaldisk
$arr = @()
foreach ($partition in $partitions){
$cims = Get-CimInstance -Query "ASSOCIATORS OF `
{Win32_DiskPartition.DeviceID='$($partition.DeviceID)'} `
WHERE AssocClass=Win32_LogicalDiskToPartition"
$regex = $partition.name -match "(\d+)"
$physDiscNr = $matches[0]
foreach ($cim in $cims){
$arr += [PSCustomObject]@{
Drive = $cim.deviceID
Partition = $partition.name
MediaType = $($physDisc | ? {$_.DeviceID -eq $physDiscNr} | select -expand MediaType)
}
}
}
$arr
It does seem kind of clunky though with the regex, so maybe there is a better approach I'm not seeing.
Upvotes: 3