Get Disk Space with PowerShell

One command returns every local drive with size, free space and free percentage — on your own PC or across a fleet of servers — using only built-in PowerShell.

PowerShell
Get-CimInstance Win32_LogicalDisk -Filter "DriveType=3" | Select-Object DeviceID, @{n="SizeGB";e={[math]::Round($_.Size/1GB,1)}}, @{n="FreeGB";e={[math]::Round($_.FreeSpace/1GB,1)}}, @{n="FreePct";e={[math]::Round($_.FreeSpace/$_.Size*100,1)}}

Paste into PowerShell 5.1 or 7 and press Enter — no administrator rights needed. Columns: DeviceID (drive letter), SizeGB, FreeGB, FreePct.

Why Win32_LogicalDisk and not Get-PSDrive?

Get-PSDrive is the file-system view: it reports Used and Free for drives the provider maps, but no total size, no free percentage and none of the volume metadata a capacity report needs. Win32_LogicalDisk is the inventory view — the same class Disk Management reads — with Size, FreeSpace, label, file system and drive type.

The DriveType=3 filter keeps only local fixed disks, so the table skips DVD drives (type 5) and mapped network drives (type 4) automatically. Leave the filter off and you get everything; change it and you get exactly the drive class you asked for.

Read-only and safe: querying Win32_LogicalDisk is a plain inventory read. It needs no elevation and none of the Windows Installer side effects that make Win32_Product a bad idea for audits.

Drive types: local, network, mounted

Swap the filter to change what the query returns:

Volumes without a drive letter of their own (for example a second volume mounted at D:Data) are not exposed by Win32_LogicalDisk — enumerate Get-CimInstance Win32_Volume for those.

Remote computers

The same query runs against many machines at once with Invoke-Command. Nothing is installed on the targets — the command needs only WinRM (enabled by default on domain-joined servers) and local administrator rights on each machine:

PowerShell
Invoke-Command -ComputerName srv01, srv02 -ScriptBlock {
    Get-CimInstance Win32_LogicalDisk -Filter "DriveType=3" |
        Select-Object DeviceID, @{n="SizeGB";e={[math]::Round($_.Size/1GB,1)}},
            @{n="FreeGB";e={[math]::Round($_.FreeSpace/1GB,1)}},
            @{n="FreePct";e={[math]::Round($_.FreeSpace/$_.Size*100,1)}}
} -Credential (Get-Credential)

-Credential (Get-Credential) prompts once and reuses the credential for both hosts; drop the parameter when your signed-in session already has rights. For a larger fleet, loop a plain-text list — one host name per line — or any CSV/AD query:

PowerShell
$servers = Get-Content .\servers.txt
foreach ($s in $servers) {
    Invoke-Command -ComputerName $s -ScriptBlock { Get-CimInstance Win32_LogicalDisk -Filter "DriveType=3" | Select-Object PSComputerName, DeviceID, @{n="FreeGB";e={[math]::Round($_.FreeSpace/1GB,1)}} }
}

For Active Directory, replace the first line with $servers = Get-ADComputer -Filter * | Select-Object -ExpandProperty Name. To eyeball results interactively, append | Out-GridView to the Invoke-Command output for a sortable grid (Windows-only).

Export to CSV

Pipe the one-liner into Export-Csv for Excel, reporting or a capacity dashboard:

PowerShell
Get-CimInstance Win32_LogicalDisk -Filter "DriveType=3" |
    Select-Object DeviceID, @{n="SizeGB";e={[math]::Round($_.Size/1GB,1)}},
        @{n="FreeGB";e={[math]::Round($_.FreeSpace/1GB,1)}},
        @{n="FreePct";e={[math]::Round($_.FreeSpace/$_.Size*100,1)}} |
    Export-Csv -Path .\disk-report.csv -NoTypeInformation

-NoTypeInformation keeps the file clean in Windows PowerShell 5.1; PowerShell 7 omits that header row by default, so the flag is a harmless no-op there. For a fleet-wide report, run the foreach loop above and pipe its collected output into Export-Csv once.

Free-space-only checks and alerts

When you need just the free number, trim the one-liner:

PowerShell
Get-CimInstance Win32_LogicalDisk -Filter "DriveType=3" | Select-Object DeviceID, @{n="FreeGB";e={[math]::Round($_.FreeSpace/1GB,1)}}

For monitoring, filter before formatting — this flags every drive under 15% free, a common alert threshold:

PowerShell
Get-CimInstance Win32_LogicalDisk -Filter "DriveType=3" |
    Where-Object { $_.FreeSpace / $_.Size -lt 0.15 } |
    Select-Object DeviceID, @{n="FreePct";e={[math]::Round($_.FreeSpace/$_.Size*100,1)}}

Adjust 0.15 to taste (0.1 = 10%). When a drive comes back low, the next step is finding what is filling it — see find large files in Windows 11 for a built-in scan.

Sort by free space

To rank drives from the least free up, append Sort-Object FreePct — the calculated property exists by the time sorting runs:

PowerShell
Get-CimInstance Win32_LogicalDisk -Filter "DriveType=3" |
    Select-Object DeviceID, @{n="SizeGB";e={[math]::Round($_.Size/1GB,1)}},
        @{n="FreeGB";e={[math]::Round($_.FreeSpace/1GB,1)}},
        @{n="FreePct";e={[math]::Round($_.FreeSpace/$_.Size*100,1)}} |
    Sort-Object FreePct

FAQ

Why does Get-PSDrive show different sizes?

Get-PSDrive reports the file-system provider's view: Used and Free for drives PowerShell maps, with no total size and no percentage, and it can omit volumes that Win32_LogicalDisk lists. The two classes read the same disks at different granularity; for capacity reports use Win32_LogicalDisk.

Is Win32_LogicalDisk safe to query?

Yes. It is a read-only inventory query that needs no elevation. The famous warning belongs to Win32_Product, which makes Windows Installer validate every MSI package and can trigger silent self-repairs; this class does none of that.

How do I check disk space on many servers at once?

Use Invoke-Command with a comma-separated -ComputerName list for a handful of hosts, or loop a servers.txt / CSV / AD list with foreach for fleets. WinRM must be reachable on the targets and you need local administrator rights there.

Does this work in PowerShell 7?

Yes. Get-CimInstance, Invoke-Command, Export-Csv and [math]::Round behave identically on Windows in PowerShell 5.1 and 7. The only cosmetic difference is that PowerShell 7 omits Export-Csv's type-info header row by default.

ITInsightHub also builds fast, ad-free networking references: