'------------------------------------------------------------------- ' Microsoft Corporation ' Copyright (c) Microsoft Corporation 2003 ' ' Monitors attributes of Logical Disk on computers that are managed by MOM (Status Monitoring). ' '------------------------------------------------------------------- ' NAME: ' ' DATE : 4/28/2005 ' ' COMMENT: ' gjm 4-26-2005 - Script was created by Microsoft to Monitor Logical Disk in MOM. I have modifed this ' to look for a file named NoDiskAlerts.MOM on the root of any drive. If this file exists ' then that drive is excluded from monitoring. ' Also adding a text file to read if the treshold needs to be changed for a logical drive. ' If the file DiskThreshold.MOM exists then a new threshold can be defined here if wanted. ' Should contain a new Percent Threshold and MB threshold. ' Same value will be used for Warning and Error. ' Line in File should contain NewPercentvalue,newMBvalue ' EXAMPLE: 3,50 ' This would be a 3 percent and 50MB threshold for the drive ' ' Functions Added to the original script - IsDriveExcluded, CollectNewThreshold, LogWSHEvent ' All lines added have comments with 'gjm' ' ' gkw 2-22-2006 - Modified CollectNewThreshold function to support bi-level alerts (warning and critical). ' If you want custom drive space monitoring to be done by MOM, then put a file ' called DiskThreshold.mom in the root of the drive you want monitored ' - (i.e. d:\diskthreshold.mom). ' ' DiskThreshold.MOM requires a single line with 4 values separated by a comma: ' CriticalPctThreshold,CriticalMBThreshold,WarningPctThreshold,WarningMBThreshold ' ' This allows you to control critical and warning alerts from MOM based on these values. ' ' DiskThreshold.MOM file setting examples: ' 10,2000,20,4000 - will create a warning alert at 20% or 4GB, then critical alert at 10% or 2GB ' If you ONLY want critical alerts, set critical and warning values the same. For example: ' 10,2000,10,2000 - will create a critical alert only at 10% or 2GB. No warning alert created. ' ' If you DON'T want a drive's disk space monitored by MOM, then put a file called NoDiskAlerts.MOM ' in the root of the drive you want to exclude. This file can be empty. ' ' If neither NoDiskAlerts.MOM nor DiskThreshold.MOM exists on a drive, then the default MOM ' rule for monitoring disk space will be applied. ' ' This RESPONSE script is called by the rule called "Run Storage State Monitoring", found here: ' Rule Groups ' Microsoft Windows Servers Base Operating System ' Windows 2003 (and Windows 2000) ' State Monitoring and Service Discovery ' and is called Scripts\Microsoft Windows Storage State Monitoring Script '========================================================================== Option Explicit ' ' Problem States ' Const PROBLEMSTATE_NOTSET = 0 Const PROBLEMSTATE_GREEN = 1 Const PROBLEMSTATE_YELLOW = 3 ' Yellow = Red+(Warning|Error) Const PROBLEMSTATE_RED = 3 ' ' Alert levels. ' Const ALERT_SUCCESS = 10 Const ALERT_INFORMATION = 20 Const ALERT_WARNING = 30 Const ALERT_ERROR = 40 Const ALERT_CRITICAL_ERROR = 50 Const ALERT_SECURITY_BREACH = 60 Const ALERT_SERVICE_UNAVAILABLE = 70 ' ' Other Constants ' Const BYTES_IN_MB = 1048576 '=2^20 Const LOCAL = 3 '****** gjm moved from MonitorDiskFreeSpace Sub Dim THRESHOLD_MB Dim THRESHOLD_PCT_RED Dim THRESHOLD_PCT_YELLOW Dim THRESHOLD_SYSTEM_PCT_RED Dim THRESHOLD_SYSTEM_PCT_YELLOW Dim THRESHOLD_MB_RED Dim THRESHOLD_MB_YELLOW Dim THRESHOLD_SYSTEM_MB_RED Dim THRESHOLD_SYSTEM_MB_YELLOW THRESHOLD_MB = GetParam("MegaByteFreeSpaceThreshold") THRESHOLD_SYSTEM_PCT_RED = GetParam("SystemDriveFreespacePercentageRedState") THRESHOLD_SYSTEM_PCT_YELLOW = GetParam("SystemDriveFreespacePercentageYellowState") THRESHOLD_PCT_RED = GetParam("NonSystemDriveFreespacePercentageRedState") THRESHOLD_PCT_YELLOW = GetParam("NonSystemDriveFreespacePercentageYellowState") THRESHOLD_SYSTEM_MB_RED = GetParam("SystemDriveFreespaceMegaByteRedState") THRESHOLD_SYSTEM_MB_YELLOW = GetParam("SystemDriveFreespaceMegaByteYellowState") THRESHOLD_MB_RED = GetParam("NonSystemDriveFreespaceMegaByteRedState") THRESHOLD_MB_YELLOW = GetParam("NonSystemDriveFreespaceMegaByteYellowState") '************************************ Sub Main() ScriptContext.Echo "Storage State Monitor (" & CStr(Time) & ")" MonitorDiskFreeSpace() ScriptContext.Echo "Complete (" & CStr(Time) & ")" End Sub Sub MonitorDiskFreeSpace() Dim IsVolumeInfoSupported : IsVolumeInfoSupported = Is_Win32_Volume_Supported() Dim oWmiDiskSet, oWmiDisk If IsVolumeInfoSupported Then Set oWmiDiskSet = WMIGetInstance("winmgmts:\\" + ScriptContext.TargetComputer & "\root\cimv2", "Win32_Volume") Else Set oWmiDiskSet = WMIGetInstance("winmgmts:\\" + ScriptContext.TargetComputer & "\root\cimv2", "Win32_LogicalDisk") End If If IsObject(oWmiDiskSet) Then For Each oWmiDisk in oWmiDiskSet If oWmiDisk.DriveType = LOCAL Then Dim sDriveLetter, nFreeSpace, nMaxSize, nPctFree, nMBFree nFreeSpace = oWmiDisk.FreeSpace If IsNull(nFreeSpace) Then _ nFreeSpace = 0 If IsVolumeInfoSupported Then sDriveLetter = oWmiDisk.DriveLetter nMaxSize = oWmiDisk.Capacity If IsNull(sDriveLetter) Then sDriveLetter = oWmiDisk.Name sDriveLetter = Left(sDriveLetter, Len(sDriveLetter)-1) End If Else sDriveLetter = oWmiDisk.DeviceId nMaxSize = oWmiDisk.Size End If If Not IsNull(nMaxSize) And nMaxSize > 0 Then ' ' Drive is formatted - if we dont get a maxsize, dont report on drive ' nPctFree = Round(nFreeSpace / nMaxSize * 100, 0) nMBFree = Round(nFreeSpace / BYTES_IN_MB, 0) ScriptContext.Echo " * " & sDriveLetter ScriptContext.Echo " + Percentage : " & nPctFree & " (" & nFreeSpace & " / " & nMaxSize & " * 100)" ScriptContext.Echo " + GigaBytes : " & nMBFree & " (" & nFreeSpace & " / " & BYTES_IN_MB & ")" Dim oAlertHandle Set oAlertHandle = ScriptContext.CreateAlert() oAlertHandle.Name = "Low disk space detected on volume " & sDriveLetter oAlertHandle.Description = "Disk volume '" & sDriveLetter & "' is low or out of free space." & vbCrLf & vbCrLf & _ "Percent Free Space: " & nPctFree & "%" & vbCrLf & _ "Capacity: " & ConvertByteToGB(nMaxSize) & " GB" & vbCrLf & _ "Used Space: " & ConvertByteToGB(nMaxSize - nFreeSpace) & " GB" & vbCrLf & _ "Free Space: " & ConvertByteToGB(nFreeSpace) & " GB" & vbCrLf & _ "Compressed: " & WMIBoolToString(oWmiDisk.Compressed) & vbCrLf & _ "File System: " & ConvertToString(oWmiDisk.FileSystem) oAlertHandle.ServerRole = "Disk" oAlertHandle.ServerRoleInstance = sDriveLetter oAlertHandle.Component = "Free Space" oAlertHandle.ProblemState = PROBLEMSTATE_GREEN oAlertHandle.AlertLevel = ALERT_SUCCESS 'Commenting out Megabyte comparison alone 'If nMBFree < CLng(THRESHOLD_MB) Then ' ScriptContext.Echo " + MegaByte Threshold Exceeded" ' oAlertHandle.ProblemState = PROBLEMSTATE_RED ' oAlertHandle.AlertLevel = ALERT_CRITICAL_ERROR 'ElseIf ' Added by gjm 4/2005 to check if Drive is excluded If Not IsDriveExcluded(sDriveLetter) Then CollectNewThreshold(sDriveLetter) If nPctFree < CInt(THRESHOLD_SYSTEM_PCT_RED) And nMBFree < CLng(THRESHOLD_SYSTEM_MB_RED) And Is_System_Drive(sDriveLetter) Then ScriptContext.Echo " + System Drive Red % Exceeded" oAlertHandle.ProblemState = PROBLEMSTATE_RED oAlertHandle.AlertLevel = ALERT_CRITICAL_ERROR ElseIf nPctFree < CInt(THRESHOLD_SYSTEM_PCT_YELLOW) And nMBFree < CLng(THRESHOLD_SYSTEM_MB_YELLOW) And Is_System_Drive(sDriveLetter) Then ScriptContext.Echo " + System Drive Yellow % Exceeded" oAlertHandle.ProblemState = PROBLEMSTATE_YELLOW oAlertHandle.AlertLevel = ALERT_WARNING ElseIf nPctFree < CInt(THRESHOLD_PCT_RED) And nMBFree < CLng(THRESHOLD_MB_RED) And Not Is_System_Drive(sDriveLetter) Then ' gjm Added not to eliminate errors ScriptContext.Echo " + Nonsystem Drive Red % Exceeded" oAlertHandle.ProblemState = PROBLEMSTATE_RED oAlertHandle.AlertLevel = ALERT_CRITICAL_ERROR ElseIf nPctFree < CInt(THRESHOLD_PCT_YELLOW) And nMBFree < CLng(THRESHOLD_MB_Yellow) And Not Is_System_Drive(sDriveLetter) Then ' gjm Added not to eliminate errors ScriptContext.Echo " + Nonsystem Drive Yellow % Exceeded" oAlertHandle.ProblemState = PROBLEMSTATE_YELLOW oAlertHandle.AlertLevel = ALERT_WARNING Else ScriptContext.Echo " + Drive Ok" oAlertHandle.Description = "There are no freespace problems with this disk. Everything is within allowable tolerances." End If Else ' Added by gjm 4/2005 to log Drive is excluded ScriptContext.Echo " + Drive Excluded" End If ScriptContext.Echo " + Submitted Alert (" & oAlertHandle.ProblemState & ", " & oAlertHandle.AlertLevel & ")" ScriptContext.Submit oAlertHandle Else ' ' If the MaxSize is 0 or less, then the drive is unformatted. ' Do not report on unformatted drives ' ScriptContext.Echo " * " & sDriveLetter ScriptContext.Echo " + Drive not formatted." End If End If Next End If End Sub Function ConvertByteToGB(sByteCount) If IsNull(sByteCount) Then ConvertByteToGB = "Not Available" Exit Function End If ConvertByteToGB = sByteCount / 1073741824.0 ConvertByteToGB = CStr( Round(ConvertByteToGB, 3) ) End Function Function ConvertToString(sString) If IsNull(sString) Then ConvertToString = "" Exit Function End If ConvertToString = CStr(sString) End Function Function WMIBoolToString(bValue) Dim sTmpValue If bValue = 1 then WMIBoolToString = "True" Else WMIBoolToString = "False" End If End Function Function GetParam(sParam) GetParam = ScriptContext.Parameters.Get(sParam) If IsEmpty(GetParam) Then ScriptContext.Echo "Script parameter '" & sParam & "' not provided." 'Throw Script Error Event End If End Function Function Is_Win32_Volume_Supported() Dim objWMISet, objWMIOS, blnRet blnRet = False Set objWMISet = WMIGetInstance("winmgmts:\\" & ScriptContext.TargetComputer & "\root\cimv2", "Win32_OperatingSystem") For each objWMIOS in objWMISet If CLng(objWMIOS.BuildNumber) >= 3624 Then blnRet = True Next Is_Win32_Volume_Supported = blnRet End Function Function Is_System_Drive(sDriveLetter) Dim objWMISet, objWMIOS Is_System_Drive = False Set objWMISet = WMIGetInstance("winmgmts:\\" & ScriptContext.TargetComputer & "\root\cimv2", "Win32_OperatingSystem") For each objWMIOS in objWMISet Dim sSystemDrive sSystemDrive = Left(objWMIOS.SystemDirectory, 2) If sSystemDrive = sDriveLetter Then Is_System_Drive = True End If Next End Function Function WMIGetInstance(sNamespace, sInstance) ' ' WMIGetInstance :: Returns WMI Instance requested. ' ' Dim oWMI, oInstance, nInstanceCount On Error Resume Next Set oWMI = GetObject(sNamespace) If IsEmpty(oWMI) Then ThrowScriptError "Unable to open WMI Namespace '" & sNamespace & "'. Check to see if the WMI service is enabled and running, and ensure this WMI namespace exists.", Err End If Set oInstance = oWMI.InstancesOf(sInstance) If IsEmpty(oInstance) Or Err.Number <> 0 Then ThrowScriptError "The class name '" & sInstance & "' returned no instances. Please check to see if this is a valid WMI class name.", Err End If 'Determine if we queried a valid WMI class - Count will return 0 or empty nInstanceCount = oInstance.Count If Err.Number <> 0 Then ThrowScriptError "The class name '" & sInstance & "' did not return any valid instances. Please check to see if this is a valid WMI class name.", Err End If On Error Goto 0 Set WMIGetInstance = oInstance Set oInstance = Nothing Set oWMI = Nothing End Function Function ThrowScriptError(sMessage, oErr) ' ' ThrowScriptError :: Creates an event and sends it back to the mom server ' ' On Error Resume Next Dim oScriptErrorEvent Set oScriptErrorEvent = ScriptContext.CreateEvent() With oScriptErrorEvent .EventNumber = 40000 .EventType = 1 'EventLogEntryType Enumeration .Message = sMessage .SetEventParameter "Microsoft Windows Servers Base Operating System" .SetEventParameter sMessage .SetEventParameter oErr.Description .SetEventParameter oErr.Number End With ScriptContext.Submit oScriptErrorEvent ScriptContext.Echo "ThrowScriptError('" & sMessage & "')" ScriptContext.Quit() End Function ' VBScript source code '********************************************************************* ' Routine: Function CollectNewThreshold(sDriveLetter) ' Purpose: Checks for the file DiskThreshold.MOM existing on the drive that the threshold needs to be changed on. ' This file should contain alert threshold values for that drive. ' Single line in file should contain RedAlertPercentvalue,RedAlertMBvalue,YellowAlertPercentvalue,YellowAlertMBvalue ' EXAMPLE: 3,50,10,200 ' This would be a 3% or 50MB threshold for RED (critical) alerts, and 10% or 200MB threshold for YELLOW (warning) alerts '********************************************************************** Function CollectNewThreshold(sDriveLetter) Dim oThresholdFile Dim sThresholdFile Dim sThresholds Dim oFSO Dim aArray Dim aArray2 sThresholdFile = sDriveLetter & "\DiskThreshold.MOM" Set oFSO = CreateObject("Scripting.FileSystemObject") If oFSO.FileExists(sThresholdFile) Then Set oThresholdFile = oFSO.OpenTextFile(sThresholdFile, 1) On Error Resume Next sThresholds = oThresholdFile.ReadAll aArray = Split(sThresholds, vbcrlf) oThresholdFile.Close On Error goto 0 Set oFSO = Nothing If Ubound(aArray) = 1 Then 'If the file has contents, continue aArray2 = Split(aArray(0), ",") If Ubound(aArray2) = 3 Then 'If the file has parm1,parm2,parm3,parm4, continue If aArray2(0) =>100 Or aArray2(2) =>100 Then 'percentage thresholds greater than 100-oops! LogWSHEvent sDriveLetter & "\DiskThreshold.MOM (first or third value) has a percentage threshold greater than or equal to 100. " &_ "Value must be LESS than 100. File contents (single line) MUST be entered as follows: " &_ "CriticalPercentThreshold,CriticalMBThreshold,WarningPercentThreshold,WarningMBThreshold.", 2 CollectNewThreshold = False Else CollectNewThreshold = True If Is_System_Drive(sDriveLetter) Then THRESHOLD_SYSTEM_PCT_RED = aArray2(0) THRESHOLD_SYSTEM_PCT_YELLOW = aArray2(2) THRESHOLD_SYSTEM_MB_RED = aArray2(1) THRESHOLD_SYSTEM_MB_YELLOW = aArray2(3) Else THRESHOLD_PCT_RED = aArray2(0) THRESHOLD_PCT_YELLOW = aArray2(2) THRESHOLD_MB_RED = aArray2(1) THRESHOLD_MB_YELLOW = aArray2(3) End If End If Else 'Incorrect number of threshold paramters in file LogWSHEvent sDriveLetter & "\DiskThreshold.MOM was detected, but the correct number of thresholds have not been defined. " &_ "Remove File or correct thresholds. File contents (single line) MUST be entered as follows: " &_ "CriticalPercentThreshold,CriticalMBThreshold,WarningPercentThreshold,WarningMBThreshold.", 2 CollectNewThreshold = False End If Else 'File Exists, but no thresholds defined. LogWSHEvent sDriveLetter & "\DiskThreshold.MOM was detected, but appears to be empty. File contents (single line) MUST be entered as follows: " &_ "CriticalPercentThreshold,CriticalMBThreshold,WarningPercentThreshold,WarningMBThreshold.", 4 wThreshold = False End If Else ' No File CollectNewThreshold = False End If End Function '********************************************************************* ' Routine: Function IsDriveExcluded(sDriveLetter) ' Purpose: To determine if drive is exclude or not. ' If a file named NoDiskAlerts.MOM exists on the drive, then exclude ' '********************************************************************** Function IsDriveExcluded(sDriveLetter) Dim sExcludeFile Dim oFSO IsDriveExcluded = False sExcludeFile = sDriveLetter & "\NoDiskAlerts.MOM" Set oFSO = CreateObject("Scripting.FileSystemObject") If oFSO.FileExists(sExcludeFile) Then IsDriveExcluded = True Else IsDriveExcluded = False End If Set oFSO = Nothing End Function '********************************************************************* ' Routine: Function LogWSHEvent(strDescription, lngSeverity) ' Purpose: Logs a WSH event in the local event Log '********************************************************************** Function LogWSHEvent(strDescription, lngSeverity) Dim objShell,blnSuccess Set objShell = CreateObject("WScript.Shell") blnSuccess = objShell.LogEvent(lngSeverity, strDescription) Set objShell = Nothing End Function