Linking disks, partitions and logical drives

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.

Advertisements
This entry was posted in PowerShell and CIM, PowerShell and WMI, Storage. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s