I administer a server VM with a lot of disks, and many of them are the same size. When I need to make changes to the system’s storage, I’m always nervous that I’m going to poke the wrong disk. I could trust that the order of the disks listed in the vSphere client is the same as the order that the guest OS lists (starting at 1 and 0 respectively). But I want a little more assurance.
Using diskpart, you can list the details for individual disks, partitions and volumes, but I wanted a report showing all the disks, the partitions on those disks, and the volumes residing on those partitions. I have reported some of this info previously, using PowerShell’s Get-WMIObject cmdlet to query the Win32_DiskDrive, Win32_Partition, and Win32_Volume classes. I figured there must me a way to correlate instances of these classes.
I found these two blog posts:
- Scripting Guy’s How Can I Correlate Logical Drives and Physical Disks?
- JRich’s Using WMI to link a Disk Volume to a Physical Disk with PowerShell
They did most of the heavy lifting in building the WQL ASSOCIATOR OF queries. I put together a short script to give me a little more detail. Here’s some sample output:
PS C:\local\scripts> .\Get-DiskInfo.ps1
Disk 0 - SCSI 0:0:2:0 - 45.00 GB
Partition 0 100.00 MB Installable File System
Partition 1 44.90 GB Installable File System
C: [NTFS] 44.90 GB ( 3.46 GB free )
[...]
Disk 5 - SCSI 0:0:2:5 - 39.99 GB
Partition 0 40.00 GB Installable File System
B: [NTFS] 40.00 GB ( 34.54 GB free )
This will make it easier to be sure about the vSphere storage element that corresponds to a particular volume (or, more accurately, the Physical Disk on which the volume resides).
Here’s the actual script:
<#
.SYNOPSIS
Get information about the physical disks and volumes on a system.
.DESCRIPTION
Get details about the physical disks and the volumes located on
those disks, to make it easier to identify corresponding vSphere
storage (VMDKs).
.EXAMPLE
PS C:\> .\Get-DiskInfo.ps1
.NOTES
Author: Geoff Duke <Geoffrey.Duke@uvm.edu>
Based on http://bit.ly/XowLns and http://bit.ly/XeIqFh
#>
Set-PSDebug -Strict
Function Main {
$diskdrives = get-wmiobject Win32_DiskDrive | sort Index
$colSize = @{Name='Size';Expression={Get-HRSize $_.Size}}
foreach ( $disk in $diskdrives ) {
$scsi_details = 'SCSI ' + $disk.SCSIBus + ':' +
$disk.SCSILogicalUnit + ':' +
$disk.SCSIPort + ':' +
$disk.SCSITargetID
write $( 'Disk ' + $disk.Index + ' - ' + $scsi_details +
' - ' + ( Get-HRSize $disk.size) )
$part_query = 'ASSOCIATORS OF {Win32_DiskDrive.DeviceID="' +
$disk.DeviceID.replace('\','\\') +
'"} WHERE AssocClass=Win32_DiskDriveToDiskPartition'
$partitions = @( get-wmiobject -query $part_query |
sort StartingOffset )
foreach ($partition in $partitions) {
$vol_query = 'ASSOCIATORS OF {Win32_DiskPartition.DeviceID="' +
$partition.DeviceID +
'"} WHERE AssocClass=Win32_LogicalDiskToPartition'
$volumes = @(get-wmiobject -query $vol_query)
write $( ' Partition ' + $partition.Index + ' ' +
( Get-HRSize $partition.Size) + ' ' +
$partition.Type
)
foreach ( $volume in $volumes) {
write $( ' ' + $volume.name +
' [' + $volume.FileSystem + '] ' +
( Get-HRSize $volume.Size ) + ' ( ' +
( Get-HRSize $volume.FreeSpace ) + ' free )'
)
} # end foreach vol
} # end foreach part
write ''
} # end foreach disk
}
#--------------------------------------------------------------------
function Get-HRSize {
[CmdletBinding()]
param(
[Parameter(Mandatory=$True, ValueFromPipeline=$True)]
[INT64] $bytes
)
process {
if ( $bytes -gt 1pb ) { "{0:N2} PB" -f ($bytes / 1pb) }
elseif ( $bytes -gt 1tb ) { "{0:N2} TB" -f ($bytes / 1tb) }
elseif ( $bytes -gt 1gb ) { "{0:N2} GB" -f ($bytes / 1gb) }
elseif ( $bytes -gt 1mb ) { "{0:N2} MB" -f ($bytes / 1mb) }
elseif ( $bytes -gt 1kb ) { "{0:N2} KB" -f ($bytes / 1kb) }
else { "{0:N} Bytes" -f $bytes }
}
} # End Function:Get-HRSize
Main
Please let me know if you find this helpful.
1 Comment