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.

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

Create a Scheduled Task

The lines below creates 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!

2 replies »

  1. 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 1 person

Leave a Reply

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

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

Google+ photo

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

Twitter picture

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

Facebook photo

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


Connecting to %s