'-------------------------------------------------------------------
' 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