PowerShell for Windows Admins

Jul 11 2017   12:35PM GMT

Linking disks, partitions and logical drives

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

Tags:
CIM
Disk storage
Powershell
WMI

A question of the forums was asking about discovering disk information. They were trying to pipe the output of Get-WmiObject into another Get-WmiObject. that won’t work. There is another way. On Windows machines physical drives are divided into 1 or more partitions which are each divided into one or more logical disks. Linking disks, partitions and logical drives is a relatively simple process.

You can start at the physical disk and work down to the logical disks or start at the logical disk and work back to the physical disk. Lets start with the logical disk.

$diskinfo = Get-CimInstance -ClassName Win32_LogicalDisk -Filter "DriveType = 3" |
foreach {
 $props = $null
 
 $part = Get-CimAssociatedInstance -InputObject $psitem -ResultClass Win32_DiskPartition
 $disk = Get-CimAssociatedInstance -InputObject $part -ResultClassName Win32_DiskDrive
 
 $props = [ordered]@{
 Disk = $disk.Index
 Model = $disk.Model
 Firmware = $disk.FirmwareRevision
 SerialNUmber = $disk.SerialNumber
 'DiskSize(GB)' = [math]::Round(($disk.Size / 1GB ), 2)
 Partitions = $disk.Partitions
 Partition = $part.index
 BootPartition = $part.BootPartition
 'PartitionSize(GB)' = [math]::Round(($part.Size / 1GB ), 2)
 Blocks = $part.NumberOfBlocks
 BlockSize = $part.BlockSize
 LDiskName = $psitem.Caption
 FileSystem = $psitem.FileSystem
 LDiskSize = [math]::Round(($psitem.Size / 1GB ), 2)
 LDiskFree = [math]::Round(($psitem.FreeSpace / 1GB ), 2)
 }

New-Object -TypeName PSObject -Property $props

}

$diskinfo

Use Get-CimInstance to retrieve the instances of the Win32_LogicalDisk class. Use a filter for DriveType = 3 – which is local disks (as far as the server is concerned – they could be on a SAN or NAS).

Foreach of the disks get the associated partition and use that object to get the associated physical drive.

CIM (WMI) has the concept of associators and references.

A reference is a pointer showing you which instance is associated with another instance. For example:

PS> Get-CimInstance -ClassName Win32_LogicalDiskToPartition


 Antecedent : Win32_DiskPartition (DeviceID = "Disk #0, Partition #1")
 Dependent : Win32_LogicalDisk (DeviceID = "C:")
EndingAddress : 511578663935
StartingAddress : 368050176
PSComputerName :

Logical disk C: is associated with partition #1 on disk #0

If you want to actually get the associated class then you do this

PS> $ld = Get-CimInstance -ClassName Win32_LogicalDisk -Filter 'DeviceID = "C:"'
 PS> Get-CimAssociatedInstance -InputObject $ld -ResultClass Win32_DiskPartition

Name NumberOfBlocks BootPartition PrimaryPartition Size Index
 ---- -------------- ------------- ---------------- ---- -----
 Disk #0, Part... 998458230 False True 511210613760 1

or

PS> Get-CimInstance -ClassName Win32_LogicalDisk -Filter 'DeviceID = "C:"' | Get-CimAssociatedInstance -ResultClass Win32_DiskPartition

Name NumberOfBlocks BootPartition PrimaryPartition Size Index
 ---- -------------- ------------- ---------------- ---- -----
 Disk #0, Part... 998458230 False True 511210613760 1

Once you’ve go the partition and physical disk instances. Populate your output object and loop. Notice that the pipeline is output directly to the variable $diskinfo. You don’t need to build arrays – get the pipeline to do it for you.

Each logical disk gets an output like this

Disk : 0
 Model : Samsung SSD 840 PRO Series
 Firmware : DXM06B0Q
SerialNUmber : S1AXNSAF329511V
DiskSize(GB) : 476.93
 Partitions : 3
 Partition : 1
BootPartition : False
PartitionSize(GB) : 476.1
 Blocks : 998458230
BlockSize : 512
LDiskName : C:
FileSystem : NTFS
LDiskSize : 476.1
LDiskFree : 212.33

That’s working up the stack. What about working down. That’s a similar process:

$diskinfo = Get-CimInstance -ClassName Win32_DiskDrive |
foreach {
 $disk = $psitem
 
 $parts = Get-CimAssociatedInstance -InputObject $psitem -ResultClass Win32_DiskPartition

foreach ($part in $parts) {
 
 Get-CimAssociatedInstance -InputObject $part -ResultClassName Win32_LogicalDisk |
 foreach {
 $props = $null

$props = [ordered]@{
 Disk = $disk.Index
 Model = $disk.Model
 Firmware = $disk.FirmwareRevision
 SerialNUmber = $disk.SerialNumber
 'DiskSize(GB)' = [math]::Round(($disk.Size / 1GB ), 2)
 Partitions = $disk.Partitions
 Partition = $part.index
 BootPartition = $part.BootPartition
 'PartitionSize(GB)' = [math]::Round(($part.Size / 1GB ), 2)
 Blocks = $part.NumberOfBlocks
 BlockSize = $part.BlockSize
 LDiskName = $psitem.Caption
 FileSystem = $psitem.FileSystem
 LDiskSize = [math]::Round(($psitem.Size / 1GB ), 2)
 LDiskFree = [math]::Round(($psitem.FreeSpace / 1GB ), 2)
 }

New-Object -TypeName PSObject -Property $props
 }
 }
 }
 $diskinfo

Start with getting the instances of Win32_Diskdrive. Foreach instance get the associated partitions – Win32_DiskPartition.

Iterate through the partitions and get the associated logical disk. Create your object and output.

NOTE: neither of these techniques will show the partitions that don’t contain logical drives so you won’t see the boot partition and other “hidden partitions” on modern Windows machines. if you need those look at Win32_DiskPartition directly.

2  Comments on this Post

 
There was an error processing your information. Please try again later.
Thanks. We'll let you know when a new response is added.
Send me notifications when other members comment.
  • JackvanDeur
    Awesome, a mighty fine example of how to put cim class association to good use. Thanks for thinking along with me. Loved what you did with the props thing. Didn't know you could do it that way. Learned a lot of this post. Thanks.
    b.t.w. Does that mean that My approach was totally wrong?
    0 pointsBadges:
    report
  • Richard Siddaway
    The mistake in your approach was in the initial attempt at piping the output of Get-wmiObject into another get-WmiObject call. That tends to be unsuccessful in most cases. You picked up on the WMI\CIM reference class and used that correctly but using get-CimAssociatedinstance is simpler. Building the properties for an object using a hashtable enables you to set the values and change them if you need to through your processing. What you're seeing in my version is the result of about 12 years working with PowerShell (I started with the early beta versions of PowerShell v1) and having spent a lot of time investigating CIM\WMI both for the book I wrote on the subject and a lot of talks I've given
    7,825 pointsBadges:
    report

Forgot Password

No problem! Submit your e-mail address below. We'll send you an e-mail containing your password.

Your password has been sent to:

Share this item with your network: