Public/system/Get-DiskSpace.ps1
|
#Requires -Version 5.1 function Get-DiskSpace { <# .SYNOPSIS Retrieves disk space information from local or remote computers .DESCRIPTION Queries Win32_LogicalDisk via CIM to return disk usage statistics for fixed drives (DriveType 3). Calculates percentage free and applies configurable warning and critical thresholds to set a health status per volume. .PARAMETER ComputerName One or more computer names to query. Defaults to the local computer. Accepts pipeline input by value and by property name. .PARAMETER WarningThreshold Percentage of free space below which the status is set to Warning. Defaults to 20 percent. .PARAMETER CriticalThreshold Percentage of free space below which the status is set to Critical. Defaults to 10 percent. .PARAMETER Credential Optional PSCredential for authenticating to remote computers. Not used for local queries. .EXAMPLE Get-DiskSpace Retrieves disk space for all fixed drives on the local computer. .EXAMPLE Get-DiskSpace -ComputerName 'SRV01' -WarningThreshold 30 -CriticalThreshold 15 Retrieves disk space from SRV01 with custom alert thresholds. .EXAMPLE 'SRV01', 'SRV02' | Get-DiskSpace Retrieves disk space from multiple servers via pipeline. .OUTPUTS PSWinOps.DiskSpace Returns one object per fixed drive with size, free space, usage percentages, and a health status based on configurable thresholds. .NOTES Author: Franck SALLET Version: 1.0.0 Last Modified: 2026-03-25 Requires: PowerShell 5.1+ / Windows only .LINK https://github.com/k9fr4n/PSWinOps .LINK https://learn.microsoft.com/en-us/windows/win32/cimwin32prov/win32-logicaldisk #> [CmdletBinding()] [OutputType('PSWinOps.DiskSpace')] param( [Parameter(Mandatory = $false, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)] [ValidateNotNullOrEmpty()] [Alias('CN', 'Name', 'DNSHostName')] [string[]]$ComputerName = $env:COMPUTERNAME, [Parameter(Mandatory = $false)] [ValidateRange(1, 100)] [int]$WarningThreshold = 20, [Parameter(Mandatory = $false)] [ValidateRange(1, 100)] [int]$CriticalThreshold = 10, [Parameter(Mandatory = $false)] [ValidateNotNull()] [System.Management.Automation.PSCredential] [System.Management.Automation.Credential()] $Credential = [System.Management.Automation.PSCredential]::Empty ) begin { Write-Verbose -Message "[$($MyInvocation.MyCommand)] Starting" $localNames = @($env:COMPUTERNAME, 'localhost', '.') if ($CriticalThreshold -ge $WarningThreshold) { Write-Warning -Message "[$($MyInvocation.MyCommand)] CriticalThreshold ($CriticalThreshold%) is >= WarningThreshold ($WarningThreshold%). Adjusting CriticalThreshold to $($WarningThreshold - 1)%." $CriticalThreshold = $WarningThreshold - 1 } } process { foreach ($machine in $ComputerName) { $cimSession = $null try { $isLocal = $localNames -contains $machine $cimParams = @{ ErrorAction = 'Stop' } if (-not $isLocal) { $sessionParams = @{ ComputerName = $machine ErrorAction = 'Stop' } if ($Credential -ne [System.Management.Automation.PSCredential]::Empty) { $sessionParams['Credential'] = $Credential } $cimSession = New-CimSession @sessionParams $cimParams['CimSession'] = $cimSession Write-Verbose -Message "[$($MyInvocation.MyCommand)] CimSession established to '$machine'" } Write-Verbose -Message "[$($MyInvocation.MyCommand)] Querying Win32_LogicalDisk on '$machine'" $disks = @(Get-CimInstance -ClassName 'Win32_LogicalDisk' -Filter 'DriveType = 3' @cimParams) $displayName = if ($isLocal) { $env:COMPUTERNAME } else { $machine } foreach ($disk in $disks) { $sizeGB = [math]::Round($disk.Size / 1GB, 2) $freeGB = [math]::Round($disk.FreeSpace / 1GB, 2) $usedGB = [math]::Round(($disk.Size - $disk.FreeSpace) / 1GB, 2) $percentFree = if ($disk.Size -gt 0) { [math]::Round(($disk.FreeSpace / $disk.Size) * 100, 1) } else { 0 } $percentUsed = [math]::Round(100 - $percentFree, 1) $status = if ($percentFree -le $CriticalThreshold) { 'Critical' } elseif ($percentFree -le $WarningThreshold) { 'Warning' } else { 'OK' } [PSCustomObject]@{ PSTypeName = 'PSWinOps.DiskSpace' ComputerName = $displayName DriveLetter = $disk.DeviceID VolumeName = $disk.VolumeName FileSystem = $disk.FileSystem SizeGB = $sizeGB FreeSpaceGB = $freeGB UsedSpaceGB = $usedGB PercentFree = $percentFree PercentUsed = $percentUsed Status = $status Timestamp = Get-Date -Format 'o' } } } catch { Write-Error -Message "[$($MyInvocation.MyCommand)] Failed on '${machine}': $_" continue } finally { if ($cimSession) { Remove-CimSession -CimSession $cimSession -ErrorAction SilentlyContinue } } } } end { Write-Verbose -Message "[$($MyInvocation.MyCommand)] Completed" } } |