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:
Implementation, 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) $SMTPClient.Send($SMTPMessage) } }
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 $Set=New-ScheduledTaskSettingsSet $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!
Categories: Cyber Security, PowerShell, Windows Server
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.
LikeLike
This is great, thank you. Very helpful.
LikeLike
You are welcome
LikeLike
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?
LikeLike
Big help, thanks! If I wanted to monitor only a small subset of servers, how could I modify this script to do so?
LikeLike
Big help! Say I want to monitor only a small subset of my servers, not all. What should I modify in order to monitor those specific servers?
LikeLike
Thank you. You can specify a list of serves and separate them by comma – server01,server02 – or place them in a text file and call them up via Get-Content
LikeLike
Thanks for the tutor.
just quick question, is script to monitoring/alert for all hard drive (drive C,D, etc)?
LikeLike
HI,
This script gets all Logical disks with drive type 3 and sends an E-Mail report if the disks are running low space.
Best,
P
LikeLike
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!
LikeLike
Hi,
I’m glad you like it!
Enjoy!
Best,
P
LikeLike
Awesome. Thanks for sharing!
LikeLiked by 1 person
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.
Regards,
MS
LikeLiked by 2 people