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