在Windows Server 2008上设置磁盘空间不足警报


29

我想知道是否有一种简单的方法来在任何逻辑磁盘分区的空间不足时触发Windows Server 2008上的电子邮件警报。由于数据库日志文件,我有2台SQL服务器接近用完磁盘空间。

谢谢,瑞安


1
如果不需要在任何长时间内保留完整日志,请将具有最大日志的数据库设置为“简单”备份模式,并让您的维护计划在完成完整备份后立即截断它们。当然,这并不能回答您的问题,但是如果您的情况允许的话,这可能有助于使驱动器首先不会变满。
贾斯汀·斯科特

谢谢(你的)信息。我确实实现了一个额外的备份作业,以帮助截断SQL日志文件并阻止它们增长。但是我想发出某种警报,以防万一。谢谢。
rmwetmore

我们使用Spiceworks来提醒我们所有客户端和服务器上的磁盘空间不足。

Answers:


37

使Windows Server 2008发送磁盘空间不足的电子邮件警报的一种简单方法是使用任务计划程序和系统日志。如果可用空间低于HKLM \ SYSTEM \ CurrentControlSet \ Services \ LanmanServer \ Parameters \ DiskSpaceThreshold中指定的百分比,则系统日志中会记录一个事件,该事件可以触发任务发送电子邮件。

  1. 打开任务计划程序并创建一个新任务。
  2. 输入任务名称,选择“运行是否登录用户”,然后选中“不存储密码”。
  3. 在“触发器”选项卡上添加新的触发器。
  4. 在“开始任务”框中选择“事件时”。
  5. 将“日志”设置为“系统”,将“源”设置为“ srv”,将事件ID设置为“ 2013”​​。
  6. 在“操作”选项卡上添加新的操作。
  7. 将“操作”设置为“发送电子邮件”,然后适当填写其余设置。
  8. 要配置何时在系统日志中记录低磁盘空间事件,请打开注册表编辑器,导航到HKLM \ SYSTEM \ CurrentControlSet \ Services \ LanmanServer \ Parameters并添加一个名为“ DiskSpaceThreshold”的DWORD值,将其设置为所需的百分比。如果该条目不存在,则默认值为10。

6
这只会触发系统驱动器(通常是C驱动器)吗?如果我有2-3个驱动程序并且要在每个驱动程序上设置警报该怎么办。
Ved

记录低于定义阈值的任何分区的事件2013-请注意,每个分区仅记录一次,除非磁盘空间增加回到阈值以上或服务器重新启动。 support.microsoft.com/kb/112509
paulH,2013年

2
在Windows Server的较新版本中,不建议使用“发送电子邮件”操作。取而代之的是,您可以使用“启动程序”操作,在powershell程序中填写以下内容并作为参数:-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

1

我通过snmp将磁盘空间监视添加到了(单独的)nagios实例。


尽管我们使用IPMonitor每隔几分钟检查一次磁盘,但我们也将磁盘监视作为常规监视程序包的一部分。
贾斯汀·斯科特

现在,我正在研究一个单独的监视系统(例如IPMonitor),但同时我想在服务器上放置一些东西以提醒我。谢谢。
rmwetmore

1

为什么不每天都将Powershell脚本作为计划任务运行?如果脚本发现磁盘的可用空间小于10%,它将向您发送电子邮件或通知。

这是检查磁盘可用空间的示例代码:

获取内容ForEach-Object {$ ; Get-WMIObject –计算机名$ Win32_LogicalDisk -filter“ DriveType = 3” | ForEach-Object {$ .DeviceID; $ .FreeSpace / 1GB}}


1
该脚本不起作用。我收到未设置任何位置参数的错误消息。
拉斐尔·卢西格

1

由于PowerShell语法不正确,两个示例都不起作用。以下代码列出了当前主机的卷大小(使用PowerShell 5.0):

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

以下代码列出了server.txt中列出的主机的卷大小:

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

边注

请注意,外部占位符$_枚举服务器地址,而内部占位符$_枚举设备。对于PowerShell新手来说,这是一个经常性的陷阱。如果要在内部循环中使用服务器地址,则必须将其分配给外部循环中的新变量。

这里使用的论坛软件有缺陷。在帖子预览中,即使没有作为代码转义,它也可以$_正确显示$_为。但是最后一篇文章删除了下划线,从而使PowerShell示例不正确。


我可以使用第一个命令看到驱动器空间剩余:Get-WmiObject win32_logicalDisk -filter "DriveType=3" | %{ $_.DeviceID; $_.FreeSpace/1GB }但是,作为PS新手,我不太了解下一步要实现此自动化(例如,如何从第一个命令获取输出,以及硬盘空间低于某个空间阈值,请连接一条PS命令以发送和发送电子邮件。我看到上面的boadad可以使用以下方式从某条帖子发送电子邮件,-command &{send-mailmessage ...但不确定如何使用逻辑来表明空间不足,因此需要发送邮件。THX。
杰夫默格勒

0

您可以使用此脚本通过电子邮件服务器发送电子邮件。只需将smtp服务器名称替换为服务器名称即可。如果在同一台计算机上,则使用“ localhost”(smtp服务器必须正常运行)。也可以在这里找到该脚本:https : //gallery.technet.microsoft.com/scriptcenter/Disk-Space-Report-Reports-98e64d65

将脚本保存在本地驱动器中后,可以使用powershell轻松运行它并进行测试。一旦脚本看起来可以正常工作,则可以使用Windows 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

我已经修复了脚本。只需创建一个名为例如server.txt的文本文件,并包含IP地址或服务器名,然后即可执行以下脚本

获取内容server.txt | foreach-object {Get-WmiObject -ComputerName 192.168.22.208 win32_logicalDisk -filter“ DriveType = 3” | ForEach-Object {$ .DeviceID; $ .FreeSpace / 1GB}}

问候,路易斯。


这实际上不是原始帖子的答案,而是对答案的更正。此外,您在代码中使用的是固定IP地址,而不是从server.txt文件中提取的值。
约翰aka hot2use

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.