PowerShell WMI – Get Disk Information

Hi guys,

Here is a small function I wrote to gather basic informations arround the Hard Drive linked to the targeted computer.

Function Get-DiskInfo {
    <#
        .SYNOPSIS
        Describe purpose of "Get-DiskInfo" in 1-2 sentences.

        .PARAMETER ComputerName
        The computer name or IP of targeted computer.

        .PARAMETER OSVersion
        The OS Version of Target Computer.

        .NOTES
        Author: Thomas Prud'homme (Twitter: @prudhommewtf).

        .LINK
        https://blog.prudhomme.wtf/powershell-wmi-get-disk-information
    #>
    [CmdletBinding()]
    Param(
        [Parameter(
            ValueFromPipeline = $true,
            ValueFromPipelineByPropertyName = $true
        )]
        [String]$ComputerName = $env:COMPUTERNAME,

        [Parameter(
            Mandatory = $true,
            ValueFromPipeline = $true,
            ValueFromPipelineByPropertyName = $true,
            HelpMessage = 'Provide the OS Version of Target Computer'
        )]
        [Version]$OSVersion
    )
    Process {
        # Win32_DiskDrive: http://msdn.microsoft.com/en-us/library/aa394132(VS.85).aspx
        # Win32_DiskDriveToDiskPartition: http://msdn.microsoft.com/en-us/library/aa394134(VS.85).aspx
        # Win32_DiskPartition: http://msdn.microsoft.com/en-us/library/aa394135(VS.85).aspx
        # Win32_LogicalDiskToPartition: http://msdn.microsoft.com/en-us/library/aa394175(VS.85).aspx
        # Win32_LogicalDisk: http://msdn.microsoft.com/en-us/library/aa394173(VS.85).aspx
        # Win32_Volume: http://msdn.microsoft.com/en-us/library/aa394515(VS.85).aspx
        $Win32_DiskDrive = Get-WMIObject -Namespace root\CIMV2 -Class Win32_DiskDrive -Property Caption, DeviceID, Interfacetype, Size -ComputerName $ComputerName
        Write-Verbose -Message 'Drive gathered information:'
        $Win32_DiskDrive | ForEach-Object {
            New-Object -TypeName PSObject -Property @{
                ComputerName  = $ComputerName
                Name          = $_.Caption
                DeviceID      = $_.DeviceID
                Interfacetype = $_.Interfacetype
                SizeBytes     = $_.Size
                Partitions    = $(
                    $Win32_DiskPartition = Get-WmiObject -Query "ASSOCIATORS OF {Win32_DiskDrive.DeviceID='$($_.DeviceID)'} WHERE AssocClass=Win32_DiskDriveToDiskPartition" -ComputerName $ComputerName
                    $Win32_DiskPartition | ForEach-Object {
                        New-Object -TypeName PSObject -Property @{
                            Name                = $_.Caption
                            StartingOffsetBytes = $_.StartingOffset
                            BlockSizeBytes      = $_.BlockSize
                            LogicalDisks        = $(
                                $PartitionDeviceID = $_.DeviceID
                                $Win32_LogicalDisk = Get-WmiObject -Namespace root\CIMV2 -Query "Associators of {Win32_DiskPartition.DeviceID=""$PartitionDeviceID""} WHERE ResultClass = Win32_LogicalDisk" -ComputerName $ComputerName
                                $Win32_LogicalDisk | Where-Object { $_.DeviceID } | ForEach-Object {
                                    # Win32_Volume only supported in Windows Server 2003 and higher
                                    if ($OSVersion -ge (New-Object -TypeName System.Version -ArgumentList '5.2')) {
                                        try {
                                            $Win32_Volume = Get-WMIObject -Namespace root\CIMV2 -Class Win32_Volume -Property BlockSize -Filter "DriveLetter = ""$($_.DeviceID)""" -ComputerName $ComputerName
                                            $AllocationUnitSizeBytes = $Win32_Volume.BlockSize
                                        }
                                        catch {
                                            $AllocationUnitSizeBytes = $null
                                        }
                                    }
                                    else {
                                        $AllocationUnitSizeBytes = $null
                                    }
                                    New-Object -TypeName PSObject -Property @{
                                        AllocationUnitSizeBytes = $AllocationUnitSizeBytes
                                        Caption                 = $_.Caption
                                        FreeSpaceBytes          = $_.FreeSpace
                                        FileSystem              = $_.FileSystem
                                        SizeBytes               = $_.Size
                                        VolumeName              = $_.VolumeName
                                    }
                                }
                            )
                        }
                    }
                )
            }
        }
    }
}