31

I was wondering if there is an easy way to trigger an e-mail alert on Windows Server 2008 when any logical disk partitions become low on space. I have 2 SQL servers that have come close to running out of disk space because of the DB log files.

Thanks, Ryan

rmwetmore
  • 432
  • 1
  • 5
  • 10
  • 1
    If you don't need to keep the full logs around for any significant period of time, set the databases with the largest logs to 'Simple' backup mode and have your maintenance plan truncate them immediately after a full backup is done. This doesn't answer your question, of course, but may help keep the drive from getting full in the first place if your situation allows it. – Justin Scott Jan 14 '10 at 16:50
  • Thanks for the info. I did implement an extra backup job to help truncate the SQL log files and keep them from growing any larger. But I would like to put some sort of alert in place just in case. Thanks. – rmwetmore Jan 14 '10 at 17:09
  • We use Spiceworks to alert us of low disk space on all clients and servers. –  Sep 30 '16 at 20:20

7 Answers7

39

One simple way to get Windows Server 2008 to send low disk space e-mail alerts is to use Task Scheduler and the System Log. If the free space falls below the percentage specified in HKLM\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters\DiskSpaceThreshold, an event is recorded in the System Log that can trigger a task to send an e-mail message.

  1. Open Task Scheduler and create a new task.
  2. Enter a name for the task, select "Run whether user is logged on or not", and check "Do not store password."
  3. Add a new trigger on the Triggers tab.
  4. Select "On an event" in the "Begin the task" box.
  5. Set Log to "System", Source to "srv", and Event ID to "2013".
  6. Add a new action on the Actions tab.
  7. Set Action to "Send an e-mail" and fill in the rest of the settings appropriately.
  8. To configure when the low disk space event is recorded in the System Log, open the Registry Editor, navigate to HKLM\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters and add a DWORD value named “DiskSpaceThreshold”, setting it to the desired percentage. When the entry does not exist, the default value is 10.
Mark Pettibone
  • 506
  • 4
  • 3
  • 6
    Does this only triggers for System drive (usually C drive) ? What if I have 2-3 driver and I want to setup alert on each of them. – Ved Oct 26 '11 at 19:13
  • Event 2013 is logged for any partition that falls below the defined threshold - note that it is only logged once per partition, unless the disk space increases back above the threshold or the server is rebooted. http://support.microsoft.com/kb/112509 – paulH Feb 04 '13 at 13:57
  • 3
    In newer versions of windows server, the "Send an e-mail" action is deprecated. Instead, you can use the "Start a Program" action, fill in `powershell` for the program and the following for arguments: `-command &{send-mailmessage -from server@domain.org -to notify@domain.com -subject 'Alert from Task Scheduler' -body 'This is an automated message from a task scheduled on the server. Testing powershell email.' -smtpserver x.x.x.x}` – Baodad May 21 '18 at 22:16
1

I added disk space monitoring via snmp to my (separate) nagios instance.

David Mackintosh
  • 14,223
  • 6
  • 46
  • 77
  • We have disk monitoring as part of our general monitoring package as well, though we use IPMonitor which cheks the disks every few minutes. – Justin Scott Jan 14 '10 at 16:56
  • Right now I'm looking into a separate monitoring system (like IPMonitor), but I would like to put something in place on the servers to alert me in the meantime. Thanks. – rmwetmore Jan 14 '10 at 17:06
1

Why don't you run a powershell script as a schedule task every day? If the script find the free space of the disk is lower than 10%, it will send you an email or notification.

here is an example code for checking the free space of the disks:

Get-Content ForEach-Object { $; Get-WMIObject –computername $ Win32_LogicalDisk -filter "DriveType=3" | ForEach-Object { $.DeviceID; $.FreeSpace/1GB } }

sky100
  • 504
  • 2
  • 3
1

Both examples do not work because of incorrect PowerShell syntax. The following code lists the volume sizes of the current host (using PowerShell 5.0):

Get-WmiObject win32_logicalDisk -filter "DriveType=3" | %{ $_.DeviceID; $_.FreeSpace/1GB }

The following code lists the volume sizes of hosts listed in server.txt:

Get-Content server.txt | %{ Get-WMIObject –computername $_ Win32_LogicalDisk -filter "DriveType=3" | %{ $_.DeviceID; $_.FreeSpace/1GB } }

Sidenote

Note that the outer place holder $_ enumerates the server addresses whereas the inner place holder $_ enumerates the devices. That's a frequent gotcha for PowerShell newbies. If you wanted to use the server address in the inner loop, you'd have to assign it to a new variable in the outer loop.

The forum software used here is flawed. In post previews, it displays $_ correctly as a $_ even if not escaped as code. But the final post removes the underscore, thus making the PowerShell examples incorrect.

  • I am able to see drive space remaining using the first command: `Get-WmiObject win32_logicalDisk -filter "DriveType=3" | %{ $_.DeviceID; $_.FreeSpace/1GB }` but being a PS newbie, I don't quite understand what the next step would be to automate this (example, how would one take the output from the first command and if the drive was below some space threshold, wire up a PS command to send and email. I see that email can be sent from a post by boadad above using `-command &{send-mailmessage ...` but unsure how to wire yours with logic that dictates that space is low mail needs to be sent. Thx. – Jeff Mergler May 24 '18 at 19:04
0

You can use this script to send an email using your email server. Just replace the name of smtp server name with that of your server. If on the same machine then use "localhost" (smtp server must be functional). The script is found here as well: https://gallery.technet.microsoft.com/scriptcenter/Disk-Space-Report-Reports-98e64d65

After the script is saved in local drive, it can be easily run using powershell and tested. Once script seems to work fine, then it can be scheduled to run everyday or every hour based on requirement using windows task scheduler. This article explains how to run a script using task scheduler. https://www.metalogix.com/help/Content%20Matrix%20Console/SharePoint%20Edition/002_HowTo/004_SharePointActions/012_SchedulingPowerShell.htm

############################################################################# 
#                                                                                                                                                     # 
#  Check disk space and send an HTML report as the body of an email.                                                   # 
#  Reports only disks on computers that have low disk space.                                                                 # 
#  Author: Mike Carmody                                                                                                                   # 
#  Some ideas extracted from Thiyagu's Exchange DiskspaceHTMLReport module.                                  # 
#  Date: 8/10/2011                                                          # 
#  I have not added any error checking into this script yet.                # 
#                                                                           # 
#                                                                           # 
############################################################################# 
# Continue even if there are errors 
$ErrorActionPreference = "Continue"; 

######################################################################################### 
# Items to change to make it work for you. 
# 
# EMAIL PROPERTIES 
#  - the $users that this report will be sent to. 
#  - near the end of the script the smtpserver, From and Subject. 

# REPORT PROPERTIES 
#  - you can edit the report path and report name of the html file that is the report.  
######################################################################################### 

# Set your warning and critical thresholds 
$percentWarning = 15; 
$percentCritcal = 10; 

# EMAIL PROPERTIES 
 # Set the recipients of the report. 
  $users = "YourDistrolist@company.com" 
    #$users = "You@company.com" # I use this for testing by uing my email address. 
  #$users = "you@company.com", "manager@company.com", "etc@company.com";  # can be sent to individuals. 


# REPORT PROPERTIES 
 # Path to the report 
  $reportPath = "D:\Jobs\DiskSpaceQuery\Reports\"; 

 # Report name 
  $reportName = "DiskSpaceRpt_$(get-date -format ddMMyyyy).html"; 

# Path and Report name together 
$diskReport = $reportPath + $reportName 

#Set colors for table cell backgrounds 
$redColor = "#FF0000" 
$orangeColor = "#FBB917" 
$whiteColor = "#FFFFFF" 

# Count if any computers have low disk space.  Do not send report if less than 1. 
$i = 0; 

# Get computer list to check disk space 
$computers = Get-Content "servers_c.txt"; 
$datetime = Get-Date -Format "MM-dd-yyyy_HHmmss"; 

# Remove the report if it has already been run today so it does not append to the existing report 
If (Test-Path $diskReport) 
    { 
        Remove-Item $diskReport 
    } 

# Cleanup old files.. 
$Daysback = "-7" 
$CurrentDate = Get-Date; 
$DateToDelete = $CurrentDate.AddDays($Daysback); 
Get-ChildItem $reportPath | Where-Object { $_.LastWriteTime -lt $DatetoDelete } | Remove-Item; 

# Create and write HTML Header of report 
$titleDate = get-date -uformat "%m-%d-%Y - %A" 
$header = " 
  <html> 
  <head> 
  <meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1'> 
  <title>DiskSpace Report</title> 
  <STYLE TYPE='text/css'> 
  <!-- 
  td { 
   font-family: Tahoma; 
   font-size: 11px; 
   border-top: 1px solid #999999; 
   border-right: 1px solid #999999; 
   border-bottom: 1px solid #999999; 
   border-left: 1px solid #999999; 
   padding-top: 0px; 
   padding-right: 0px; 
   padding-bottom: 0px; 
   padding-left: 0px; 
  } 
  body { 
   margin-left: 5px; 
   margin-top: 5px; 
   margin-right: 0px; 
   margin-bottom: 10px; 
   table { 
   border: thin solid #000000; 
  } 
  --> 
  </style> 
  </head> 
  <body> 
  <table width='100%'> 
  <tr bgcolor='#CCCCCC'> 
  <td colspan='7' height='25' align='center'> 
  <font face='tahoma' color='#003399' size='4'><strong>AEM Environment DiskSpace Report for $titledate</strong></font> 
  </td> 
  </tr> 
  </table> 
" 
 Add-Content $diskReport $header 

# Create and write Table header for report 
 $tableHeader = " 
 <table width='100%'><tbody> 
 <tr bgcolor=#CCCCCC> 
    <td width='10%' align='center'>Server</td> 
 <td width='5%' align='center'>Drive</td> 
 <td width='15%' align='center'>Drive Label</td> 
 <td width='10%' align='center'>Total Capacity(GB)</td> 
 <td width='10%' align='center'>Used Capacity(GB)</td> 
 <td width='10%' align='center'>Free Space(GB)</td> 
 <td width='5%' align='center'>Freespace %</td> 
 </tr> 
" 
Add-Content $diskReport $tableHeader 

# Start processing disk space reports against a list of servers 
  foreach($computer in $computers) 
 {  
 $disks = Get-WmiObject -ComputerName $computer -Class Win32_LogicalDisk -Filter "DriveType = 3" 
 $computer = $computer.toupper() 
  foreach($disk in $disks) 
 {         
  $deviceID = $disk.DeviceID; 
        $volName = $disk.VolumeName; 
  [float]$size = $disk.Size; 
  [float]$freespace = $disk.FreeSpace;  
  $percentFree = [Math]::Round(($freespace / $size) * 100, 2); 
  $sizeGB = [Math]::Round($size / 1073741824, 2); 
  $freeSpaceGB = [Math]::Round($freespace / 1073741824, 2); 
        $usedSpaceGB = $sizeGB - $freeSpaceGB; 
        $color = $whiteColor; 

# Set background color to Orange if just a warning 
 if($percentFree -lt $percentWarning)       
  { 
    $color = $orangeColor  

# Set background color to Orange if space is Critical 
      if($percentFree -lt $percentCritcal) 
        { 
        $color = $redColor 
       }         

 # Create table data rows  
    $dataRow = " 
  <tr> 
        <td width='10%'>$computer</td> 
  <td width='5%' align='center'>$deviceID</td> 
  <td width='15%' >$volName</td> 
  <td width='10%' align='center'>$sizeGB</td> 
  <td width='10%' align='center'>$usedSpaceGB</td> 
  <td width='10%' align='center'>$freeSpaceGB</td> 
  <td width='5%' bgcolor=`'$color`' align='center'>$percentFree</td> 
  </tr> 
" 
Add-Content $diskReport $dataRow; 
Write-Host -ForegroundColor DarkYellow "$computer $deviceID percentage free space = $percentFree"; 
    $i++   
  } 
 } 
} 

# Create table at end of report showing legend of colors for the critical and warning 
 $tableDescription = " 
 </table><br><table width='20%'> 
 <tr bgcolor='White'> 
    <td width='10%' align='center' bgcolor='#FBB917'>Warning less than 15% free space</td> 
 <td width='10%' align='center' bgcolor='#FF0000'>Critical less than 10% free space</td> 
 </tr> 
" 
  Add-Content $diskReport $tableDescription 
 Add-Content $diskReport "</body></html>" 

# Send Notification if alert $i is greater then 0 
if ($i -gt 0) 
{ 
    foreach ($user in $users) 
{ 
        Write-Host "Sending Email notification to $user" 

  $smtpServer = "MySMTPServer" 
  $smtp = New-Object Net.Mail.SmtpClient($smtpServer) 
  $msg = New-Object Net.Mail.MailMessage 
  $msg.To.Add($user) 
        $msg.From = "myself@company.com" 
  $msg.Subject = "Environment DiskSpace Report for $titledate" 
        $msg.IsBodyHTML = $true 
        $msg.Body = get-content $diskReport 
  $smtp.Send($msg) 
        $body = "" 
    } 
  } 
-1

I have fixed the script. Just create a text file named for example server.txt and include the ip address or servernames and then you can execute the following script

Get-Content server.txt | foreach-object{Get-WmiObject -ComputerName 192.168.22.208 win32_logicalDisk -filter "DriveType=3"|ForEach-Object{$.DeviceID; $.FreeSpace/1GB}}

Regards, Luis.

  • This is not really an answer to the original posting, but a correction to an answer. Additionally you are using a fixed IP address in the code instead of the value extracted from the server.txt file. – John K. N. Nov 24 '16 at 15:00
-1

Get-Content server.txt | foreach-object{Get-WmiObject -ComputerName xx.xx.xx.xx win32_logicalDisk -filter "DriveType=3" | forEach-Object{$.DeviceID; $.FreeSpace/1GB}}