Public/Hardware/Get-StorageInfo.ps1

<#
Copyright © 2024 Integris. For internal company use only. All rights reserved.
#>


FUNCTION Get-StorageInfo {
    <#
    .SYNOPSIS
    Retrieves and displays detailed information about storage devices and partitions on the system.
 
    .DESCRIPTION
    This function collects information about each partition and disk, including partition size, volume free space, disk model, bus type, and serial number. It also identifies unpartitioned disks and calculates the total and unallocated space.
 
    .EXAMPLE
    Get-StorageInfo
 
    This command retrieves and displays detailed information about all storage devices and partitions on the system.
 
    .NOTES
    This function uses CIM instances to gather storage information and may require appropriate permissions to execute.
    #>


    [CmdletBinding()]
    PARAM ( )

    $Results = @()
    $Partitions = Get-Partition
    $DisksWithPartitions = @()

    FOREACH($Partition in $Partitions) {
        IF ($Partition.Type -eq "Reserved" ) { continue }
        
        $PartitionSizeUnit = "GB"
        $VolumeSizeUnit = "GB"
        $Disk = Get-Disk $Partition.DiskNumber
        $VolumeUniqueID = ($Partition.AccessPaths | Where-Object { $_ -like "*Volume*" })
        $Volume = Get-Volume | Where-Object { $_.UniqueId -eq "$VolumeUniqueID" }
        $Disk = Get-Disk $Partition.DiskNumber
        
        $BusType = $null
        IF ($Disk.PhysicalLocation  -like "*BaseLayer*") { $BusType = "Sandbox" }
        ELSE { $BusType = $Disk.BusType }
        
        $DiskType = ""

        $PartitionTotalSpace = ""
        $PartitionSizeUnit = ""
        $VolumeFreeSpace = ""
        $VolumeTotalSpace = ""
        $VolumeFreePercent = ""

        $DisksWithPartitions += $Disk.SerialNumber

        IF($null -ne $VolumeUniqueID) {
            TRY {
                [int]$PartitionTotalSpace = [MATH]::Round(($Partition.Size / 1GB))
                IF ($PartitionTotalSpace -eq 0) { 0/0 }
                [string]$PartitionSizeUnit = "GB"
                [string]$PartitionTotalSpace = ($PartitionTotalSpace.ToString() + " $PartitionSizeUnit")
            }
            CATCH {
                [int]$PartitionTotalSpace = [MATH]::Round(($Partition.Size / 1MB))
                [string]$PartitionSizeUnit = "MB"
                [string]$PartitionTotalSpace = ($PartitionTotalSpace.ToString() + " $PartitionSizeUnit")
            }

            TRY {
                $VolumeFreeSpace = [MATH]::Round(($Volume.SizeRemaining / 1GB))
                $VolumeTotalSpace = [MATH]::Round(($Volume.Size / 1GB))
                [int]$VolumeFreePercent = [MATH]::Round(($VolumeFreeSpace / $VolumeTotalSpace * 100),0)
                $VolumeSizeUnit = "GB"
                $VolumeFreeSpace = ($VolumeFreeSpace.ToString() + " $VolumeSizeUnit")
                $VolumeTotalSpace = ($VolumeTotalSpace.ToString() + " $VolumeSizeUnit")
                [string]$VolumeFreePercent = ($VolumeFreePercent.ToString() + "%")
            }
            CATCH {
                $VolumeFreeSpace = [MATH]::Round(($Volume.SizeRemaining / 1MB))
                $VolumeTotalSpace = [MATH]::Round(($Volume.Size / 1MB))
                TRY { [int]$VolumeFreePercent = [MATH]::Round(($VolumeFreeSpace / $VolumeTotalSpace * 100),0) } CATCH { [int]$VolumeFreePercent = 0 }
                $VolumeSizeUnit = "MB"
                $VolumeFreeSpace = ($VolumeFreeSpace.ToString() + " $VolumeSizeUnit")
                $VolumeTotalSpace = ($VolumeTotalSpace.ToString() + " $VolumeSizeUnit")
                [string]$VolumeFreePercent = ($VolumeFreePercent.ToString() + "%")
            }
        }
        ELSE {
            TRY {
                $PartitionTotalSpace = [MATH]::Round(($Partition.Size / 1GB))
                IF ($PartitionTotalSpace -eq 0) { 0/0 }
                $PartitionSizeUnit = "GB"
                $PartitionTotalSpace = ($PartitionTotalSpace.ToString() + " $PartitionSizeUnit")
            }
            CATCH {
                [int]$PartitionTotalSpace = [MATH]::Round(($Partition.Size / 1MB))
                [string]$PartitionSizeUnit = "MB"
                [string]$PartitionTotalSpace = ($PartitionTotalSpace.ToString() + " $PartitionSizeUnit")
            }

            TRY {
                [string]$VolumeFreeSpace = ""
                [string]$VolumeTotalSpace = ""
                [string]$VolumeFreePercent = ""
                [string]$SizeUnit = "GB"
            }
            CATCH {
                [string]$VolumeFreeSpace = ""
                [string]$VolumeTotalSpace = ""
                [string]$VolumeFreePercent = ""
                [string]$SizeUnit = "MB"
            }
        }  
        
        IF ($Null -ne $Partition.MBRType) { $DiskType = "MBR" }
        ELSE { $DiskType = "GPT" }  

        $UnallocatedSpace = [MATH]::Round((($Disk.Size - $Disk.AllocatedSize) / 1GB),0)

        TRY { $VolumeUniqueID = $VolumeUniqueID.Replace("\\?\Volume{","").Replace("}\","").ToUpper() } CATCH {}

        IF ($Disk.SerialNumber.Length -eq 36 -or $Disk.SerialNumber.Length -eq 38) { $SerialNumber = "" }
        ELSE { $SerialNumber = $Disk.SerialNumber }

        $Results += New-Object PSObject -WarningAction SilentlyContinue -Property @{
            PSTypeName = 'IntegrisPowerShell.StorageInfo'
            Hostname = $env:COMPUTERNAME
            Letter = $Partition.DriveLetter
            PartNumber = $Partition.PartitionNumber
            PartType = $Partition.Type
            PartSize = $PartitionTotalSpace
            VolumeGUID = $VolumeUniqueIDGet
            FileSystem = $Volume.FileSystem
            VolFreePercent = $VolumeFreePercent
            VolFree = $VolumeFreeSpace
            VolTotal = $VolumeTotalSpace
            DiskModel = $Disk.Model
            DiskBus = $BusType
            DiskType = $DiskType
            DiskGUID = $Disk.GUID
            DiskAllocatedSpace = [MATH]::Round(($Disk.AllocatedSize / 1GB))
            DiskTotal = [MATH]::Round(($Disk.Size / 1GB)).ToString() + " GB"
            DiskUnallocated = $UnallocatedSpace.ToString() + " GB"
            DiskSerial = $SerialNumber
        }
    }

    FOREACH ($Disk in (Get-PhysicalDisk)) {
        IF ($DisksWithPartitions -contains $Disk.SerialNumber) { continue }
        IF ($Disk.CannotPoolReason -eq "In a Pool") { continue }

        $UnallocatedSpace = [MATH]::Round((($Disk.Size - $Disk.AllocatedSize) / 1GB),0)

        IF ($Disk.SerialNumber.Length -eq 36 -or $Disk.SerialNumber.Length -eq 48) { $SerialNumber = "" }
        ELSE { $SerialNumber = $Disk.SerialNumber }

        $BusType = $null
        IF ($Disk.PhysicalLocation  -like "*BaseLayer*") { $BusType = "Sandbox" }
        ELSE { $BusType = $Disk.BusType }

        $Results += New-Object PSObject -WarningAction SilentlyContinue -Property @{
            PSTypeName = 'IntegrisPowerShell.StorageInfo'
            Hostname = $env:COMPUTERNAME
            Letter = ""
            PartitionNumber = ""
            PartType = "Unpartitioned"
            PartSize = ""
            VolumeGUID = ""
            FileSystem = ""
            VolFreePercent = ""
            VolFree = ""
            VolTotal = ""
            DiskModel = $Disk.Model
            DiskBus = $BusType
            DiskType = ""
            DiskGUID = $Disk.GUID
            DiskAllocatedSpace = [MATH]::Round(($Disk.AllocatedSize / 1GB))
            DiskTotal = [MATH]::Round(($Disk.Size / 1GB)).ToString() + " GB"
            DiskUnallocated = $UnallocatedSpace.ToString() + " GB"
            DiskSerial = $SerialNumber
        }
    }

    RETURN $Results | Sort-Object -Property PartType,Letter
}
New-Alias -Name Get-StorageDevice -Value Get-StorageInfo