Skip to content

Get-DiskSpaceReport

Reporting: Generates an HTML disk space report for local or remote computers

#Requires -Version 5.1

[CmdletBinding()]
Param(
    [string[]]$ComputerName = @('localhost'),

    [int]$ThresholdPercent = 15,

    [string]$OutputPath = ''
)

Process {
    try {
        $diskData = @()
        foreach ($computer in $ComputerName) {
            try {
                $disks = Get-CimInstance -ClassName Win32_LogicalDisk -ComputerName $computer -Filter "DriveType=3" -ErrorAction Stop
                foreach ($disk in $disks) {
                    $size = $disk.Size
                    $free = $disk.FreeSpace
                    
                    if ($null -eq $size -or $size -eq 0) { continue }
                    
                    $percentFree = [Math]::Round(($free / $size) * 100, 2)
                    $sizeGB = [Math]::Round($size / 1GB, 2)
                    $freeGB = [Math]::Round($free / 1GB, 2)
                    $usedGB = [Math]::Round(($size - $free) / 1GB, 2)

                    $status = if ($percentFree -lt $ThresholdPercent) { 'Critical' } else { 'Healthy' }

                    $diskData += [PSCustomObject]@{
                        Computer    = $computer.ToUpper()
                        Drive       = $disk.DeviceID
                        VolumeName  = $disk.VolumeName
                        SizeGB      = $sizeGB
                        UsedGB      = $usedGB
                        FreeGB      = $freeGB
                        PercentFree = $percentFree
                        Status      = $status
                    }
                }
            }
            catch {
                Write-Warning "Failed to query computer '$computer': $_"
            }
        }

        if ($diskData.Count -eq 0) {
            Write-Output "No disk data retrieved."
            return
        }

        # Build clean styled HTML report
        $html = @'
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Disk Space Report</title>
    <style>
        body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; margin: 30px; background-color: #f5f7fa; color: #333; }
        h1 { color: #2c3e50; border-bottom: 2px solid #3498db; padding-bottom: 10px; }
        .timestamp { color: #7f8c8d; font-size: 0.9em; margin-bottom: 20px; }
        table { border-collapse: collapse; width: 100%; box-shadow: 0 4px 6px rgba(0,0,0,0.1); background-color: white; border-radius: 4px; overflow: hidden; }
        th, td { padding: 12px 15px; text-align: left; border-bottom: 1px solid #e1e8ed; }
        th { background-color: #34495e; color: white; font-weight: 600; text-transform: uppercase; font-size: 0.85em; letter-spacing: 0.5px; }
        tr:hover { background-color: #f1f5f9; }
        .critical { background-color: #fadbd8; color: #c0392b; font-weight: bold; }
        .badge { padding: 4px 8px; border-radius: 12px; font-size: 0.8em; font-weight: bold; text-transform: uppercase; }
        .badge-healthy { background-color: #2ecc71; color: white; }
        .badge-critical { background-color: #e74c3c; color: white; }
    </style>
</head>
<body>
    <h1>Disk Space Status Report</h1>
'@
        $html += "    <div class='timestamp'>Generated: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') | Warning Threshold: < $ThresholdPercent% Free</div>"
        $html += "    <table>"
        $html += "        <tr>"
        $html += "            <th>Computer</th><th>Drive</th><th>Volume Name</th><th>Size (GB)</th><th>Used (GB)</th><th>Free (GB)</th><th>% Free</th><th>Status</th>"
        $html += "        </tr>"

        foreach ($row in $diskData) {
            $classAttr = if ($row.Status -eq 'Critical') { " class='critical'" } else { "" }
            $badgeAttr = if ($row.Status -eq 'Critical') { "<span class='badge badge-critical'>Critical</span>" } else { "<span class='badge badge-healthy'>Healthy</span>" }
            
            $html += "        <tr$classAttr>"
            $html += "            <td>$($row.Computer)</td>"
            $html += "            <td>$($row.Drive)</td>"
            $html += "            <td>$($row.VolumeName)</td>"
            $html += "            <td>$($row.SizeGB)</td>"
            $html += "            <td>$($row.UsedGB)</td>"
            $html += "            <td>$($row.FreeGB)</td>"
            $html += "            <td>$($row.PercentFree)%</td>"
            $html += "            <td>$badgeAttr</td>"
            $html += "        </tr>"
        }

        $html += @'
    </table>
</body>
</html>
'@

        if ($OutputPath) {
            $parentDir = Split-Path -Path $OutputPath -Parent
            if ($parentDir -and -not (Test-Path -Path $parentDir)) {
                New-Item -ItemType Directory -Path $parentDir -Force | Out-Null
            }
            $html | Out-File -FilePath $OutputPath -Encoding utf8 -Force
            Write-Host "Disk space report written to: $OutputPath"
        } else {
            Write-Output $html
        }
    }
    catch {
        Write-Error $_
        throw
    }
}

One or more computer names or IP addresses to query

Disk free space percentage threshold. Items with free space below this will be highlighted in Red.

Optional file path to save the generated HTML report

An interactive directory of PowerShell scripts.