I have a VBScript that I have pieced together from various scripts I have found to monitor hard drive space, memory usage, and processor usage. The script works but I want it to do more.
Currently it reads a list of servers from a txt file, checks hard drive space, if hard drive space is less than n% sends an email, then checks cpu, if cpu usage is high send an email, then checks memory, if memory usage is high send an email.
Here is what I want to add, I would like it to automatically pull list of servers out of ad domain controllers and my ad servers ou instead of a txt file so that I do not have to update the file when a server is added or deleted. Next I would like the functionality to be a continuous loop whereas if hard drive free space is low send out an email alert ONCE and only once per incident, when hard drive space is increased send alert that free space is now within acceptable level, if hard drive free space is and was within acceptable level no email alerts. And do the same for CPU and memory. We currently us a program to do that but we are getting rid of it because it is unreliable and major budget cuts (We cannot purchase any new program for this). Any help would be greatly appreciated and any other feedback to make the script even better.
WATCH OUT FOR LINE WRAPPING IN BELOW CODE!
Const LOCAL_HARD_DISK = 3 ' 3 is all local drives.
Const FOR_READING = 1
Const CONVERSION = 1073741824 ' This is total bytes in 1 GB.
Const CONVERT = 1048576 ' This is total bytes in 1 MB.
On Error Resume Next
strLocal = "."
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile("servers.txt", FOR_READING)
Do Until objFile.AtEndOfStream
strComputer = objFile.ReadLine
Set objWMIService1 = GetObject("winmgmts:\\" & strLocal & "\root\cimv2")
Set colPings = objWMIService1.ExecQuery _
("Select * From Win32_PingStatus where Address = '" & strComputer & "'")
'WScript.Echo strComputer
' Check if server is alive before getting info.
For Each objStatus in colPings
If IsNull(objStatus.StatusCode) or objStatus.StatusCode <> 0 Then
Else
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colDisks = objWMIService.ExecQuery _
("SELECT * FROM Win32_LogicalDisk WHERE DriveType = " & LOCAL_HARD_DISK & "")
For Each objDisk in colDisks
intFreeSpace = objDisk.FreeSpace / CONVERSION
intTotalSpace = objDisk.Size / CONVERSION
pctFreeSpace = intFreeSpace / intTotalSpace
'Wscript.Echo pctFreeSpace & " on " & strComputer
If pctFreeSpace < .15 Then
strSubject = UCase(strComputer) & objDisk.DeviceID & " Free space low"
strBody = Now & vbCrLf & UCase(strComputer) _
& " available disk space is below the 15% threshold on " & objDisk.DeviceID & " with " & FormatPercent(pctFreeSpace) & " available!" & vbCrLf _
& vbCrLf & "Total Space: " & FormatNumber(intTotalSpace, 2, False, False, True) & "GB" & vbCrLf _
& "Free Space: " & FormatNumber(intFreeSpace, 2, False, False, True) & "GB"
call MAILER(strComputer, strSubject, strBody)
End If
Next
'Gets PROCESSOR Usage
set objRefresher = CreateObject("WbemScripting.Swbemrefresher")
Set objProcessor = objRefresher.AddEnum _
(objWMIService, "Win32_PerfFormattedData_PerfOS_Processor").objectSet
intThresholdViolations = 0
objRefresher.Refresh
For Each intProcessorUse in objProcessor
If intProcessorUse.PercentProcessorTime > 90 Then
intThresholdViolations = intThresholdViolations + 1
If intThresholdViolations = 1 Then
intThresholdViolations = 0
strSubject = UCase(strComputer) & " CPU usage high"
strBody = Now & vbCrLf & UCase(strComputer) & "Processor usage threshold exceeded. " & intProcessorUse.PercentProcessorTime & "% Usage"
call MAILER(strComputer, strSubject, strBody)
End If
Else
intThresholdViolations = 0
End If
Next
'Gets MEMORY Usage
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\CIMV2")
Set colSettings = objWMIService.ExecQuery ("Select * from Win32_OperatingSystem")
For Each objOperatingSystem in colSettings
intFreeMem = objOperatingSystem.FreePhysicalMemory / CONVERT
intTotalMem = objOperatingSystem.TotalVisibleMemorySize / CONVERT
pctMem = intFreeMem / intTotalMem
If pctMem < .10 Then
strSubject = UCase(strComputer) & " Memory usage high"
strBody = Now & vbCrLf & UCase(strComputer) _
& " Memory usage is above the 90% threshold with " & FormatPercent(pctMem, 2, False, False, True) & vbCrLf & vbCrLf _
& "Total Memory: " & FormatNumber(intTotalMem, 2, False, False, True) & "Gb" & vbCrLf _
& "Free Memory: " & FormatNumber(intFreeMem, 2, False, False, True) & "Gb"
call MAILER(strComputer, strSubject, strBody)
End If
Next
End If
Next
Loop
objFile.Close
'#####################
'# Sub To Send Email #
'#####################
Sub MAILER(Computer, Subject, Body)
' strLength = Len(Wscript.ScriptName) - 4
'strFrom = Left(Wscript.ScriptName, strLength)
Set objEmail = CreateObject("CDO.Message")
objEmail.From = strFrom & "Administrator@domain.com"
objEmail.To = "me@domain.com; otherpersons@domain.com"
objEmail.Subject = Subject
objEmail.TextBody = Body
objEmail.Configuration.Fields.Item _
(" = 2
objEmail.Configuration.Fields.Item _
(" = "exchange.domain.com"
objEmail.Configuration.Fields.Item _
(" = 25
objEmail.Configuration.Fields.Update
objEmail.Send
End sub
Currently it reads a list of servers from a txt file, checks hard drive space, if hard drive space is less than n% sends an email, then checks cpu, if cpu usage is high send an email, then checks memory, if memory usage is high send an email.
Here is what I want to add, I would like it to automatically pull list of servers out of ad domain controllers and my ad servers ou instead of a txt file so that I do not have to update the file when a server is added or deleted. Next I would like the functionality to be a continuous loop whereas if hard drive free space is low send out an email alert ONCE and only once per incident, when hard drive space is increased send alert that free space is now within acceptable level, if hard drive free space is and was within acceptable level no email alerts. And do the same for CPU and memory. We currently us a program to do that but we are getting rid of it because it is unreliable and major budget cuts (We cannot purchase any new program for this). Any help would be greatly appreciated and any other feedback to make the script even better.
WATCH OUT FOR LINE WRAPPING IN BELOW CODE!
Const LOCAL_HARD_DISK = 3 ' 3 is all local drives.
Const FOR_READING = 1
Const CONVERSION = 1073741824 ' This is total bytes in 1 GB.
Const CONVERT = 1048576 ' This is total bytes in 1 MB.
On Error Resume Next
strLocal = "."
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile("servers.txt", FOR_READING)
Do Until objFile.AtEndOfStream
strComputer = objFile.ReadLine
Set objWMIService1 = GetObject("winmgmts:\\" & strLocal & "\root\cimv2")
Set colPings = objWMIService1.ExecQuery _
("Select * From Win32_PingStatus where Address = '" & strComputer & "'")
'WScript.Echo strComputer
' Check if server is alive before getting info.
For Each objStatus in colPings
If IsNull(objStatus.StatusCode) or objStatus.StatusCode <> 0 Then
Else
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colDisks = objWMIService.ExecQuery _
("SELECT * FROM Win32_LogicalDisk WHERE DriveType = " & LOCAL_HARD_DISK & "")
For Each objDisk in colDisks
intFreeSpace = objDisk.FreeSpace / CONVERSION
intTotalSpace = objDisk.Size / CONVERSION
pctFreeSpace = intFreeSpace / intTotalSpace
'Wscript.Echo pctFreeSpace & " on " & strComputer
If pctFreeSpace < .15 Then
strSubject = UCase(strComputer) & objDisk.DeviceID & " Free space low"
strBody = Now & vbCrLf & UCase(strComputer) _
& " available disk space is below the 15% threshold on " & objDisk.DeviceID & " with " & FormatPercent(pctFreeSpace) & " available!" & vbCrLf _
& vbCrLf & "Total Space: " & FormatNumber(intTotalSpace, 2, False, False, True) & "GB" & vbCrLf _
& "Free Space: " & FormatNumber(intFreeSpace, 2, False, False, True) & "GB"
call MAILER(strComputer, strSubject, strBody)
End If
Next
'Gets PROCESSOR Usage
set objRefresher = CreateObject("WbemScripting.Swbemrefresher")
Set objProcessor = objRefresher.AddEnum _
(objWMIService, "Win32_PerfFormattedData_PerfOS_Processor").objectSet
intThresholdViolations = 0
objRefresher.Refresh
For Each intProcessorUse in objProcessor
If intProcessorUse.PercentProcessorTime > 90 Then
intThresholdViolations = intThresholdViolations + 1
If intThresholdViolations = 1 Then
intThresholdViolations = 0
strSubject = UCase(strComputer) & " CPU usage high"
strBody = Now & vbCrLf & UCase(strComputer) & "Processor usage threshold exceeded. " & intProcessorUse.PercentProcessorTime & "% Usage"
call MAILER(strComputer, strSubject, strBody)
End If
Else
intThresholdViolations = 0
End If
Next
'Gets MEMORY Usage
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\CIMV2")
Set colSettings = objWMIService.ExecQuery ("Select * from Win32_OperatingSystem")
For Each objOperatingSystem in colSettings
intFreeMem = objOperatingSystem.FreePhysicalMemory / CONVERT
intTotalMem = objOperatingSystem.TotalVisibleMemorySize / CONVERT
pctMem = intFreeMem / intTotalMem
If pctMem < .10 Then
strSubject = UCase(strComputer) & " Memory usage high"
strBody = Now & vbCrLf & UCase(strComputer) _
& " Memory usage is above the 90% threshold with " & FormatPercent(pctMem, 2, False, False, True) & vbCrLf & vbCrLf _
& "Total Memory: " & FormatNumber(intTotalMem, 2, False, False, True) & "Gb" & vbCrLf _
& "Free Memory: " & FormatNumber(intFreeMem, 2, False, False, True) & "Gb"
call MAILER(strComputer, strSubject, strBody)
End If
Next
End If
Next
Loop
objFile.Close
'#####################
'# Sub To Send Email #
'#####################
Sub MAILER(Computer, Subject, Body)
' strLength = Len(Wscript.ScriptName) - 4
'strFrom = Left(Wscript.ScriptName, strLength)
Set objEmail = CreateObject("CDO.Message")
objEmail.From = strFrom & "Administrator@domain.com"
objEmail.To = "me@domain.com; otherpersons@domain.com"
objEmail.Subject = Subject
objEmail.TextBody = Body
objEmail.Configuration.Fields.Item _
(" = 2
objEmail.Configuration.Fields.Item _
(" = "exchange.domain.com"
objEmail.Configuration.Fields.Item _
(" = 25
objEmail.Configuration.Fields.Update
objEmail.Send
End sub