PowerShell Disk Management: Check and Manage Drives

PowerShell Disk Management: Check and Manage Drives

PowerShell Tips Editor 4 min read
PowerShell Disk Management: Check and Manage Drives

Provisioning a new server means initializing, partitioning, and formatting a raw disk — and doing it through the Disk Management GUI is not repeatable or scriptable. PowerShell disk management via the Storage module (Get-Disk, Get-Partition, Get-Volume) gives you full control over disks and volumes without opening a single GUI. From checking disk health and free space to creating and formatting new partitions, everything here is automatable and auditable.

List All Disks and Health Status

Get-Disk returns all physical disks recognized by the system including USB drives and virtual disks. The HealthStatus and OperationalStatus properties are the first things to check during troubleshooting.

Get-Disk | Select-Object Number, FriendlyName, HealthStatus, OperationalStatus,
    @{ N="SizeGB"; E={ [math]::Round($_.Size / 1GB, 1) } }, PartitionStyle
Number  FriendlyName           HealthStatus  OperationalStatus  SizeGB  PartitionStyle
------  ------------           ------------  -----------------  ------  --------------
0       Samsung SSD 970 EVO    Healthy       Online             238.5   GPT
1       WD Blue 2TB            Healthy       Online             1862.9  GPT
2       (new disk)             Healthy       Offline            500.1   RAW

Get Partition and Volume Info

Get-Partition shows the partitions on each disk. Get-Volume shows the logical volumes with drive letters and file system types. Combine them for a complete picture of disk layout.

# Partitions on disk 0
Get-Partition -DiskNumber 0 | Select-Object DiskNumber, PartitionNumber, DriveLetter,
    @{ N="SizeGB"; E={ [math]::Round($_.Size / 1GB, 1) } }, Type

# All volumes with free space
Get-Volume | Where-Object DriveType -eq "Fixed" |
    Select-Object DriveLetter, FileSystemLabel, FileSystem,
        @{ N="SizeGB"; E={ [math]::Round($_.Size / 1GB, 1) } },
        @{ N="FreeGB"; E={ [math]::Round($_.SizeRemaining / 1GB, 1) } }

Check Free Space on All Drives

Building a low-disk-space report is a common monitoring script. Calculate the free percentage and flag any drive below a threshold.

$threshold = 15  # Alert if free space below 15%

Get-Volume | Where-Object { $_.DriveType -eq "Fixed" -and $_.Size -gt 0 } |
    ForEach-Object {
        $freePct = [math]::Round(($_.SizeRemaining / $_.Size) * 100, 1)
        [PSCustomObject]@{
            Drive   = $_.DriveLetter
            Label   = $_.FileSystemLabel
            FreeGB  = [math]::Round($_.SizeRemaining / 1GB, 1)
            TotalGB = [math]::Round($_.Size / 1GB, 1)
            FreePct = $freePct
            Alert   = $freePct -lt $threshold
        }
    } | Format-Table -AutoSize

Initialize and Format a New Disk

A new or RAW disk must be initialized, partitioned, and formatted before use. This process is destructive to existing data on the disk — always verify the disk number first. Requires administrator rights.

# DANGER: Verify disk number before running — this destroys all data on the disk
$diskNumber = 2

# Initialize with GPT partition style
Initialize-Disk -Number $diskNumber -PartitionStyle GPT

# Create a new partition using all available space
$partition = New-Partition -DiskNumber $diskNumber -UseMaximumSize -AssignDriveLetter

# Format as NTFS
Format-Volume -DriveLetter $partition.DriveLetter `
    -FileSystem NTFS `
    -NewFileSystemLabel "DataDisk" `
    -Confirm:$false

Write-Output "Disk $diskNumber formatted as drive $($partition.DriveLetter):"

Resize a Partition

You can shrink or extend a partition without losing data, as long as the file system supports it (NTFS does). Get the support range first to know the valid boundaries.

# Check min/max supported sizes for resize
$supportedSize = Get-PartitionSupportedSize -DriveLetter "C"
Write-Output "Min: $([math]::Round($supportedSize.SizeMin/1GB,1)) GB — Max: $([math]::Round($supportedSize.SizeMax/1GB,1)) GB"

# Resize the partition (extend to 200 GB in this example)
Resize-Partition -DriveLetter "D" -Size 200GB

Alert on Low Disk Space

Combine the free-space check with an email alert or event log write for an automated monitoring solution. This pattern works well in a scheduled task that runs every hour.

$alerts = Get-Volume | Where-Object { $_.DriveType -eq "Fixed" -and $_.Size -gt 0 } |
    Where-Object { ($_.SizeRemaining / $_.Size) -lt 0.10 }

foreach ($vol in $alerts) {
    $msg = "LOW DISK SPACE: Drive $($vol.DriveLetter): on $env:COMPUTERNAME — " +
           "$([math]::Round($vol.SizeRemaining/1GB,1)) GB free"
    Write-EventLog -LogName Application -Source "DiskMonitor" -EventId 9001 `
        -EntryType Warning -Message $msg
    Write-Warning $msg
}

Common Errors and Fixes

  • Disk operations require admin rights: Initialize-Disk, New-Partition, Format-Volume, and Resize-Partition all require an elevated PowerShell session. Running without elevation produces “Access is denied” or “Invalid Parameter” errors. Right-click PowerShell and choose “Run as administrator,” or use Start-Process pwsh -Verb RunAs from a script launcher.
  • Initialize-Disk destroys existing data — confirm first: Initialize-Disk on a disk that already contains data will wipe the partition table. Add a safety check before running: use Get-Disk -Number $diskNumber | Where-Object PartitionStyle -eq "RAW" to confirm the disk is truly uninitialized before proceeding. Build in a Read-Host confirmation prompt in any interactive script.

Related Cmdlets / See Also

Wrapping Up

The Storage module covers the complete disk lifecycle — from health checks and space reporting to initialization and formatting — all without touching a GUI. As a next step, add the low-disk-space alert script to a scheduled task that runs hourly and writes to the Application event log, then configure an alert in your monitoring platform to catch those events before disks fill up.

Send-Item -To