Cyber Security

PowerShell: Alert me when Disk Space is running low on my Windows Servers (E-Mail Notification)

Without any doubt, you should have an eye on the disk space of your servers. I’ve seen so many servers crashing due to dropping disk space over time, because of saving more and more files and data or because of Windows Updates. They were running Exchange, SQL, AD and all of them were important servers with crucial software on it. If you are currently not monitoring disk free spaces and if you don’t have an enterprise tool like SCCM at hand then this article is for you. We do it all with PowerShell, what else? Let’s jump in.

As mentioned, the goal is to implement a monitoring solution to monitor all Windows Servers. To achieve this, we need a couple of things:

  • All Windows Server by Name (best with a cleaned up Active Directory environment, with no orphaned computer accounts)
  • A foreach loop with Get-WmiObject win32_logicaldisk to get disk free space from all servers
  • An if statement in the loop to get only notified of servers with low disk space
  • E-Mail Configuration (maybe with a password in it, be sure, I will take care of this problem and provide you a solution)

The Goal

Defining the goal is easy. We want to get an E-Mail when one of the server is running on low disk space. The E-Mail should look like this:

Capture.PNGImplementation, on the other hand, is a little more difficult. This brings me to the script.

The Script

The following script alerts you if one of your servers has less than 10 % disk space.

### Getting all domain-joined Server by Names

$servers=(Get-ADComputer -Filter 'operatingsystem -like "*server*"').Name

### Get only DriveType 3 (Local Disks) foreach Server

ForEach ($s in $servers)

{$Report=Get-WmiObject win32_logicaldisk -ComputerName $s -Filter "Drivetype=3" -ErrorAction SilentlyContinue | Where-Object {($_.freespace/$_.size) -le '0.1'}
$View=($Report.DeviceID -join ",").Replace(":","")
### Send Mail if $Report (<=10%) is true

If ($Report)


$EmailTo = "p.gruenauer@domain.xy"
$EmailFrom = "alert@domain.xy"
$user = 'p.gruenauer@domain.xy'
$password = Unprotect-CmsMessage -Path C:\Temp\pw.txt
$Subject = "Alert: PowerShell Storage Report of $s"
$Body = "Server $s storage space has dropped to less than 10 % on $View"
$SMTPServer = "smtp.domain.xy"
$SMTPMessage = New-Object System.Net.Mail.MailMessage($EmailFrom,$EmailTo,$Subject,$Body)
$SMTPClient = New-Object Net.Mail.SmtpClient($SmtpServer, 587)
$SMTPClient.EnableSsl = $true
$SMTPClient.Credentials = New-Object System.Net.NetworkCredential($user, $password)



You have to edit line 17,18,19,20 and 23 to your fits.

Line 20 is very interesting. For sending an E-Mail you usually have to authenticate your account to the E-Mail server. This also means that the password has to be saved in your script. To avoid this, encrypt the password file as described here PowerShell: Encrypt and Decrypt Data by using Certificates (Public Key / Private Key)

Unprotect-CmsMessage decrypts the file’s content. Remember that you are hopefully the only one who has the private key and therefore you are the only one on this planet who can decrypt the password file.

If you like it, copy it into your PowerShell ISE session and save it as C:\PowerShell\alert_diskspace.ps1.

Create a Scheduled Task

Finally we will wrap up our script into a Scheduled Task that runs every day.

The lines below create a scheduled task that runs C:\PowerShell\alert_diskspace.ps1 once a day (08:00 am).

You may want to edit the file path in line 1 and you have to modify the UserId in line 4.

$Action=New-ScheduledTaskAction -Execute "powershell" -Argument "C:\PowerShell\alert_diskspace.ps1"
$Trigger=New-ScheduledTaskTrigger -Daily -At 08am
$Principal=New-ScheduledTaskPrincipal -UserId "sid-500\patrick" -LogonType S4U
$Task=New-ScheduledTask -Action $Action -Trigger $Trigger -Settings $Set -Principal $Principal -Description "Checks free disk space on all Servers. Sends an E-Mail notification if storage drops below 10%"
Register-ScheduledTask -TaskName "Free Disk Space Check" -InputObject $Task -User "sid-500\patrick" -Password (Read-Host 'Enter Password') -Force

That’s it. Your severs are monitored.

See you next time with PowerShell again!

28 replies »

  1. Hi ,

    I wanted to one automate script for regarding from windows server to local machine copying the log files for daily days.

    Could you please share the script for this.


  2. This is going to send one email for each server that has low space, right? So if I have 20 servers with low space, Im’ going to get 20 emails? Is there any way to maybe take the information it returns and create a list of them and then just send one email with the list?


  3. Big help, thanks! If I wanted to monitor only a small subset of servers, how could I modify this script to do so?


  4. This was just what I was looking for today! Thanks.. had some issues with the smtp.send, but have resolved those now. Got what I needed at zero cost, so hopefully running out of space will be an old problem now, and we can be more proactive!


  5. Thanks for the script and the useful approach.

    Just to add one other if condition of the disk was not under 10%, to out-file to a log file, so the admin can track the changes in size over time which might be useful for scaliablity.


    Liked by 2 people

Leave a Reply to Tom Bosley Cancel reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.