In this article we will show you how to check the free disk space and disk usage on a local or remote Windows host using PowerShell. Also, consider how to notify the administrator with a pop-up notification or email if the free space threshold is exceeded.
How to Check Drive Free Space on Windows with WMI and PowerShell?
You can get information about your logical drives in Windows using the Win32_logicalDisk WMI class.
The command below will display all information about the logical drives on your computer:
Get-WmiObject -Class Win32_LogicalDisk
The term 'Get-WmiObject' is not recognized as a name of a cmdlet, function, script file, or executable program
. Use CIM instead of WMI, for example:Get-CimInstance win32_logicaldisk
The FreeSpace property contains the amount of free space in bytes left on each of the drives. To make it more convenient, you can convert it to GB and display the amount of free space on each logical disk in % (as the ratio of free space to the total disk size). You can use the following PowerShell script:
Get-WmiObject -Class Win32_LogicalDisk |
Select-Object -Property DeviceID, VolumeName, @{Label='FreeSpace (Gb)'; expression={($_.FreeSpace/1GB).ToString('F2')}},
@{Label='Total (Gb)'; expression={($_.Size/1GB).ToString('F2')}},
@{label='FreePercent'; expression={[Math]::Round(($_.freespace / $_.size) * 100, 2)}}|ft
The script displays a list of logical drives, their size, and free space percentage.
Get-WmiObject
with Get-CimInstance
.If you don’t want to simply display the information about the free space on a disk, but take some action instead (send an e-mail or show a popup message) if there is less free space than the specified threshold, you can use the PowerShell script below:
$percentWarning = 20
$percentCritcal = 5
$ListDisk = Get-WmiObject -Class Win32_LogicalDisk
Foreach($Disk in $ListDisk){
if ($Disk.size -ne $NULL) {
$DiskFreeSpace = ($Disk.freespace/1GB).ToString('F2')
$DiskFreeSpacePercent = [Math]::Round(($Disk.freespace/$Disk.size) * 100, 2)
if($DiskFreeSpacePercent -lt $percentWarning){
$Message= "Warning!"
if($DiskFreeSpacePercent -lt $percentCritcal){
$Message= "Alert!"
}
$wshell = New-Object -ComObject Wscript.Shell
$Output = $wshell.Popup("Disk $($Disk.DeviceID) has only $DiskFreeSpace GB of free space left",0,$Message,48)
}
}
}
This script sets threshold values of free space left on a disk — 5% and 20%. If the amount of free space on any of the disks is below the specified values, a modal information window is displayed. You can show it as a pop-up notification or immediately run the Disk Cleanup tool (cleanmgr.exe
).
If you would like to email the administrator of the problem, you can send an email via an SMTP server (it may be Exchange host or any other SMTP service, even the built-in Windows Server SMTP role will do) with the Send-MailMessage cmdlet:
Send-MailMessage -To “[email protected]” -From “$env:[email protected]” -Subject “Insufficient disk space on server $env:computername” -Body “Disk $($Disk.DeviceID) has only $DiskFreeSpace GB left” -Credential (Get-Credential) -SmtpServer smtp.woshub.com -Port 587
You can run the PowerShell script regularly using the Task Scheduler or it can be configured as a Windows service. If there is not enough free space on the this Windows host, an administrator will get a notification.
Get Free Disk Space from Remote Windows Hosts via PowerShell
The Invoke-Command cmdlet can be used to run a PS script to check the remaining free space on remote computers.
Invoke-Command -ComputerName srv01,srv02,srv03 -FilePath "C:\PS\checkfreespace.ps1"
If the servers you want to check the amount of free space on are in your domain, you can get the list of them from Active Directory using the Get-ADComputer cmdlet and run the script against each host:
$computers = (Get-ADComputer -Filter 'operatingsystem -like "*Windows Server*" -and enabled -eq "true"').Name
Invoke-Command -ComputerName $computers -FilePath "C:\PS\checkfreespace.ps1" -ErrorAction SilentlyContinue
You can also use RemoteWMI to get WMI data from remote computers:
Get-WmiObject -Class Win32_logicalDisk -ComputerName srv01,srv02,srv03
2 comments
and this works on domain servers. but it is not working on non-domain machines.
can you explain how to get this working to remote monitor on non domain servers? thanks
In order to use the Invoke-Command to connect to non-domain devices, you need to configure the WinRM (PowerShell remoting) with TrustedHost (or configure WinRM SSL – the harder way)