'==========================================================================
'File:                  ProcessWatchdog.vbs
'Version:               1.0
'Author:                Bennett Scharf www.bennett-scharf.com
'Purpose:               This script is used to terminate a hung process.  You can configure
'                       the process name, the maximum run time, notification options, And
'                       logging options.
'                       Note: This script is designed to loop continuoulsy.  I was careful to ensure that
'                       destructors were included in all the correct places to eliminate memory leaks.
'                       Normally I trigger this via a Task Scheduler job that runs at startup.
'Creation Date:         25 May 2005
'Revision Date: n/a
'Related Files:         cscript.exe -vbscript console command intrepreter part of standard OS install
'                       ProcessWatchdog.reg  - registry export file showing config parameters
'                       VBSendMail.dll, a popular SMTP component for sending mail via an SMTP server
'Registry Settings      See file ProcessWatchdog.reg  Typical registry settings at the end of this file.
'
'Operating System:      Windows 2000
'Usage:                 cscript ProcessWatchdog.vbs
'Exit codes:            Normal exit: 0, Error Exit >0
'==========================================================================
Option Explicit

'Constants are generally stored here
'Configuration values are stored in the registry -- see ReadConfigVariable function
Const strProcName "'SomeProcess.exe'" 'Process to be monitored be sure to enclose process name in single quotes!
Const strRegPath "HKLM\Software\ScharfCo\Monitoring\"

While 1
   CheckProcesses
   WScript.Sleep
(300000)
Wend
   
Sub 
CheckProcesses
'At present this is the main routine
   
Dim strComputerintProcessAgeintMaxAge  
   
Dim objWMIServicecolProcessListobjProcess
   intMaxAge 
ReadConfigVariable("WatchdogMaxAge")
   
strComputer "."
   
Set objWMIService GetObject("winmgmts:\\" strComputer "\root\cimv2")
   
Set colProcessList objWMIService.ExecQuery _
       
("SELECT * FROM Win32_Process WHERE Name = " strProcName)
   
For Each objProcess In colProcessList
       intProcessAge 
GetProcessAge(objProcess.CreationDate)
       
If intProcessAge intMaxAge Then
           
LogProcessTermination objProcess.ProcessIdintProcessAgeUTCtoDate(objProcess.CreationDate)
           
AlertProcessTermination objProcess.ProcessIdintProcessAgeUTCtoDate(objProcess.CreationDate)
           
objProcess.terminate
       
End If
   Next
   Set 
objWMIService = Nothing    
   Set 
colProcessList = Nothing
   Set 
objProcess = Nothing
End Sub

Function 
ReadConfigVariable(strVarName)
'Passed name of variable in registry path
'Returns variable contents from registry path
   
Dim WshShell
   
Set WshShell Wscript.CreateObject("WScript.Shell")
   
ReadConfigVariable WshShell.RegRead(strRegPath strVarName)
   
Set WshShell = Nothing
End Function    


Function 
GetProcessAge(datCreationDate)
'Passed creation date in WMI format
'Returns process age in minutes (in VB format)
   
Dim datVbCreationDate        'creation date in VB format
   
If Not IsNull(datCreationDateThen
       
datVbCreationDate UTCtoDate(datCreationDate)
       
GetProcessAge DateDiff("n"datVbCreationDateNow)
   
Else
       
GetProcessAge 0
   
End If
End Function


Function 
UTCtoDate(UTCDate)
'Passed date in UTC format
'Returns date in VB format
   
UTCtoDate = CDate(Mid(UTCDate52) & "/" _
       Mid
(UTCDate72) & "/" _
       Left
(UTCDate4) & " " _
       Mid 
(UTCDate92) & ":" _
       Mid
(UTCDate112) & ":" _
       Mid
(UTCDate132))
End Function

Sub 
LogProcessTermination(intProcessIDintProcessAgedatCreationDate)
'writes facts about process termination to a log file
   
Const ForReading 1ForWriting 2ForAppending 8
   
Dim strLogPath
   
Dim objLogFile
   
Dim fso
   
Set fso CreateObject("Scripting.FileSystemObject")
   
strLogPath ReadConfigVariable("WatchdogLogPath")
   
If Not(fso.FileExists(strLogPath)) Then
   
'if the file doesn't exist, create it and write a hheader row
       
On Error Resume Next
       Set 
objLogFile fso.OpenTextFile(strLogPathForWritingTrue)
       
If Err.Number <> Then 'Trap file open errors and exit
           
Wscript.echo Err.Description
           Wscript.quit 
(Err.Number)
       
End If
       On Error GoTo 
0
       objLogfile.writeline 
"Time,PID,Age,Created"
       
objLogfile.Close
       Set 
objLogfile = Nothing
   End If       
   Set 
objLogFile fso.OpenTextFile(strLogPathForAppendingTrue)
   
objLogFile.writeline Now "," intProcessID "," intProcessAge "," datCreationDate
   objLogFile.
Close
   Set 
objLogFile = Nothing
   Set 
fso = Nothing
End Sub


Sub 
AlertProcessTermination(intProcessIdintProcessAgedatCreationDate)
'Send alert via SMTP
   
Dim strRecipientsstrSMTPHoststrSMTPFromstrSMTPFromDisplayName
   
Dim objSendMail
   strRecipients 
ReadConfigVariable("WatchdogRecipients")
   
strSMTPHost ReadConfigVariable("WatchdogSMTPHost")
   
strSMTPFrom ReadConfigVariable("WatchdogSMTPFrom")
   
strSMTPFromDisplayName ReadConfigVariable("WatchdogSMTPDisplayName")
   
   
Set objSendMail CreateObject("vbSendMail.clsSendMail")
   
objSendMail.SMTPHost strSMTPHost
   objSendMail.From 
strSMTPFrom
   objSendMail.FromDisplayName 
strSMTPFromDisplayName
   objSendMail.Recipient 
strRecipients
   objSendMail.Subject 
"Process Termination"
   
objSendMail.Message "A Global Vision Server Process exceeded the maximum age and was terminated." _
       VbCrLf 
"Server: " GetServerName _
       VbCrlf 
"Process ID: " intProcessID _
       VbCrlf 
"Process Age: " intProcessAge/60 " hours" _
       VbCrLf 
"Process Creation Time: " datCreationDate
   objSendMail.Send
   
Set objSendMail = Nothing
End Sub

Function 
GetServerName
'Returns local server name
   
Dim WshShellWshSysEnv
   
Set WshShell WScript.CreateObject("WScript.Shell")
   
Set WshSysEnv WshShell.Environment("PROCESS")
   
GetServerName WshSysEnv("COMPUTERNAME")
   
Set WshShell = Nothing
   Set 
WshSysEnv = Nothing
End Function


' Typical registry settings

' [HKEY_LOCAL_MACHINE\SOFTWARE\Scharfco\Monitoring]
' "WatchdogLogPath"="d:\\test.txt"
' "WatchdogMaxAge"=dword:0000001e
' "WatchdogRecipients"="bennett.scharf@test.net"
' "WatchdogSMTPHost"="mailexchanger.test.net"
' "WatchdogSMTPFrom"="notify@test.net"
' "WatchdogSMTPDisplayName"="GVI Process WatchDog"