Notification of low disk space (Mount points too) and Handle Alert Suppression–PowerShell


We have a server of approval, yes I know it’s approval, but because of holidays and how we are a major retailer, this server has become critical to the business, given that many changes are made ​​to the systems at this time.

As our monitoring process is a bit bureaucratic to happen, we needed a quick solution for verification of low disk space on this server. Solution. Powershell and WMI

I wanted to build a more flexible solution possible, so I thought of a way to the script get all the server volumes and report on a value below X (passed parameter). My first version was:

   1: $Hostname = 'Server01'

   2: $Space = 2048

   3: $SpaceGB =  $Space / 1024

   4: Get-WmiObject               -computername $Hostname  `

   5:                              -query " select Name  from Win32_Volume where  DriveType = 3 and SystemVolume = false and FileSystem = 'NTFS'"              | foreach {

   6:  

   7:                try {

   8:  

   9:                                $Volume = ($($_.name).TrimEnd("\")).replace("\" ,"\\")

  10:                                $SourceIdentifier = (($($_.name)).replace("\" ,"")).replace(":","")

  11:                                $query = "Select * from __instanceModificationEvent WITHIN 5 WHERE TargetInstance ISA 'Win32_PerfFormattedData_PerfDisk_LogicalDisk' and targetinstance.Name=`'$($Volume)`' AND TargetInstance.freemegabytes < $space"

  12:                                Register-WMIEvent       -ComputerName $Hostname `

  13:                                                        -Query  $Query  `

  14:                                                          -SourceIdentifier "LowDiskSpace$($SourceIdentifier)" `

  15:                                                          -Action    {

  16:                                                                         $Gb = "{0:n2}" -f ($event.SourceEventArgs.NewEvent.targetinstance.FreeMegabytes/1024);

  17:                                                                         Send-MailMessage        -SmtpServer XXX.X.XX.XXX -From 'SQLExecutive@contoso.com' -To  'laerte.junior@contoso.com.br' -Subject "Espaco em Disco Abaixo de $($SpaceGB) GB - Servidor  $($event.SourceEventArgs.NewEvent.targetinstance.__SERVER)" -Body " Volume $($event.SourceEventArgs.NewEvent.targetinstance.name) com $Gb GB";

  18:                                                                         Write-EventLog -LogName MonitorLowDiskSpace -EventId 01 -Message "Espaco em Disco Abaixo de $($SpaceGB) GB - Servidor  $($event.SourceEventArgs.NewEvent.targetinstance.__SERVER) Volume $($event.SourceEventArgs.NewEvent.targetinstance.name) com $Gb GB"  -Source Poshevent -EntryType Warning -Category 1 -ComputerName $Hostname

  19:  

  20:                                                                     } | Out-Null

  21:                                $log = "Event registered in Volume $($Volume) computer $($Hostname)" 

  22:  

  23:                } catch {

  24:                                $Log = "Failed to Register WMI Event on {0} volume {2}. {1}" -f $($Hostname),$($Volume),$($_.Exception.Message)

  25:                }

  26:                $log | Out-File "$Env:TEMP\MsgEvents$(Get-date -format 'ddMMyyyy').log" -Append

  27: }

  28: Send-MailMessage        -SmtpServer XXX.X.XX.XXX -From 'SQLExecutive@contoso.com' -To  'laerte.junior@contoso.com.br' -Subject "Eventos de Espaco em Disco" -Body "Script de Registro de evento em espaco em disco executado no servidor $($Hostname). Verificar Arquivo de log $Env:TEMP\MsgEvents$(Get-date -format 'ddMMyyyy').log ";

  29:  

  30:  

Lets see some things :
 

First I need to find the volumes, that is because I am using Win32_Volume and properties DriveType = 3 and SystemVolume = false and FileSystem = ‘NTFS’.
The drive type = 1 show only Local Disk, System Volume = false to not use system volume and FileSystem = ‘NTFS’ only want the NTFS formatted volumes.
Then I am using Win32_PerfFormattedData_PerfDisk_LogicalDisk class to get the data from this volumes .

in this line
$Volume = ($($_.name).TrimEnd(“\”)).replace(“\” ,”\\”)

I formated the volume to take off the ‘\’ at the end of the volume, because the mount points is showed as d:\something\ and I change the ‘\’ to ‘\\’ because ‘\’ is a special char.

in this line
$SourceIdentifier = (($($_.name)).replace(“\” ,””)).replace(“:”,””)

I cleaned  the volume name to concatenate in –SourceIdentifier “LowDiskSpace$($SourceIdentifier)”. This way I haveJob Name each event registered

Then I createed a Log File with messsage successful or failed and put at $env:temp
$log | Out-File “$Env:TEMP\MsgEvents$(Get-date -format ‘ddMMyyyy’).log” -Append

This way I do not have a email to each event registered or not, juts one email to see the log file at $Env:TEMP\MsgEvents$(Get-date -format ‘ddMMyyyy’).log

Also Created a new Entry in EventViewer called MonitorLowDiskSpace to log the data into EventViewer too.

New-EventLog MonitorLowDiskSpace -source PoshEvent

And  was working fine, but in the first problem with disk space a message each 5 seconds was delivery to my email. (within clause to 5)
Then, I changed to 30 minutes (1800 seconds). But, other problem. when the low disk space happened again, the first email only was delivery after 30 minutes. Bummer.
So, I decided to create my own alert suppression.

Handle with alert Suppression

My Idea is simple. Just create a log file with the date and hour that the email was sent and then in the next execution I test if the minutes between current date (get-date) and the data logged into the file is greater than X minutes. (Pareameter $Time). If it is, send email again and update the file with the current date time. No, just ignore it.

So the code is :

   1: #New-EventLog MonitorLowDiskSpace -source PoshEvent

   2: Param      (

   3:                  [ValidateNotNullOrEmpty()] $Hostname,

   4:                  [ValidateNotNullOrEmpty()] $Space

   5:                  [ValidateNotNullOrEmpty()] $Time

   6:  

   7:            )

   8: #$Hostname = 'Server01'

   9: #$Space = 2048

  10: #Time 10 -minutes

  11: $SpaceGB =  $Space / 1024

  12: Get-WmiObject               -computername $Hostname  `

  13:                              -query " select Name  from Win32_Volume where  DriveType = 3 and SystemVolume = false and FileSystem = 'NTFS'"              | foreach {

  14:  

  15:                try {

  16:  

  17:                               $Volume = ($($_.name).TrimEnd("\")).replace("\" ,"\\")

  18:                               $SourceIdentifier = (($($_.name)).replace("\" ,"")).replace(":","")

  19:                               $SourceIdentifier = "LowDiskSpace$($SourceIdentifier)" 

  20:                               $FileName = "$($Env:TEMP)\$($SourceIdentifier).log"

  21:                               $pso = new-object psobject -property @{FileName=$FileName;Time=$Time}              

  22:  

  23:                                $query = "Select * from __instanceModificationEvent WITHIN 5 WHERE TargetInstance ISA 'Win32_PerfFormattedData_PerfDisk_LogicalDisk' and targetinstance.Name=`'$($Volume)`' AND TargetInstance.freemegabytes < $space"

  24:                                Register-WMIEvent       -ComputerName $Hostname `

  25:                                                        -Query  $Query  `

  26:                                                          -SourceIdentifier $SourceIdentifier `

  27:                                                          -Action    {

  28:                                                                         $SendEmail = $true

  29:                                                                         if (Test-Path $event.MessageData.FileName  -PathType Leaf ) {

  30:                                                                               $SendEmail = ((New-TimeSpan -Start ([datetime]::parseexact((get-content $event.MessageData.FileName),'yyyy-MM-dd HH:mm:ss',$null)) -End (get-date -format "yyyy-MM-dd HH:mm:ss")).totalminutes -ge  $event.MessageData.Time) ;

  31:                                                                         }

  32:  

  33:                                                                         if ($SendEmail) {

  34:                                                                               $Gb = "{0:n2}" -f ($event.SourceEventArgs.NewEvent.targetinstance.FreeMegabytes/1024);

  35:                                                                               Send-MailMessage      -SmtpServer XXX.X.XX.XXX -From 'SQLExecutive@contoso.com' -To  'laerte.junior@contoso.com.br'  -Subject "Espaco em Disco Abaixo de $($SpaceGB) GB - Servidor  $($event.SourceEventArgs.NewEvent.targetinstance.__SERVER)" -Body " Volume $($event.SourceEventArgs.NewEvent.targetinstance.name) com $Gb GB";

  36:                                                                               Write-EventLog -LogName MonitorLowDiskSpace -EventId 01 -Message "Espaco em Disco Abaixo de $($SpaceGB) GB - Servidor  $($event.SourceEventArgs.NewEvent.targetinstance.__SERVER) Volume $($event.SourceEventArgs.NewEvent.targetinstance.name) com $Gb GB"  -Source Poshevent -EntryType Warning -Category 1 -ComputerName $Hostname

  37:                                                                               get-date -format 'yyyy-MM-dd HH:mm:ss' | Out-File  $event.MessageData.FileName -Force 

  38:                                                                         }

  39:  

  40:                                                                     } | Out-Null

  41:                                $log = "Event registered in Volume $($Volume) computer $($Hostname)" 

  42:  

  43:                } catch {

  44:                                $Log = "Failed to Register WMI Event on {0} volume {2}. {1}" -f $($Hostname),$($Volume),$($_.Exception.Message)

  45:                }

  46:                $log | Out-File "$Env:TEMP\MsgEvents$(Get-date -format 'ddMMyyyy').log" -Append

  47: }

  48: Send-MailMessage        -SmtpServer XXX.X.XX.XXX -From 'SQLExecutive@contoso.com' -To  'laerte.junior@contoso.com.br' -Subject "Eventos de Espaco em Disco" -Body "Script de Registro de evento em espaco em disco executado no servidor $($Hostname). Verificar Arquivo de log $Env:TEMP\MsgEvents$(Get-date -format 'ddMMyyyy').log ";

  49:  

  50:  

Big Thanks to Shay Levy to help in my datetime questions Alegre

Download  LowDiskSpace.ps1

#PowerShellLifeStyle

About Laerte Junior

Laerte Junior Laerte Junior is a SQL Server specialist and an active member of WW SQL Server and the Windows PowerShell community. He also is a huge Star Wars fan (yes, he has the Darth Vader´s Helmet with the voice changer). He has a passion for DC comics and living the simple life. "May The Force be with all of us"
This entry was posted in Powershell, SQL SERVER EM GERAL, Virtual Pass BR. Bookmark the permalink.

Leave a Reply

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

WordPress.com Logo

You are commenting using your WordPress.com 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