' ********************************************************************* ' ' Name : RespondAfterX.vbs ' Author : 3Ds (UK) Limited ' Description : Example VBScript to show how to perform actions after X ' no. errors within a given timeframe. It also uses CDO ' to send an e-mail indicating that it has been run etc. ' Script Type : Alerting. ' Arguments : None ' Returns : 0 - Success, 1 - An error occurred. ' Notes : Requires Windows Scripting Host (for VBScript), ' Microsoft CDO 2000 or above. ' ' Change the "TODOs" for your own requirements. ' ' WIZARD:PARAMS=This script requires no parameters ' WIZARD:PARAMEXAMPLE= ' WIZARD:RESULTS=Return code ...||0 = OK|1 = An error prevented the script from running.||Script output also indicates "OK" for success, or "Error" with details of the faults found. ' ' ********************************************************************* ' Enable in-line error handling On Error Resume Next ' ------ Local declarations ------ ' Constants Const cdoSendUsingPickup = 1 ' Send message local SMTP service pickup directory. Const cdoSendUsingPort = 2 ' Send the message using the network (SMTP over the network). Const cDefaultSMTPPort = 25 ' The port your SMTP server listens on - typically 25 Const cREADFILE = 1 ' Read access Const cWRITEFILE = 2 ' Write access Const cHIDE = 0 ' Hide the window Const cSHOW = 1 ' Show the window Const cMAX_ENTRIES = TODO: Enter max. events per response here (e.g. 5) ' Max entries to save ' Declare variables Dim strTimeNow ' Time now Dim strAlertTime ' Latest alert time Dim strLoggedTimes(TODO: Enter same number as cMAX_ENTRIES here) ' Logged time array Dim strSMTPServer ' Our SMTP Server Dim strSMTPUser ' Our SMTP User Dim strSMTPPassword ' Our SMTP User's password Dim strSender ' The sending e-mail address Dim strRecipient ' The target e-mail address Dim strTitle ' Message title Dim strMessage ' Message text Dim strDetectedErrorMessage ' Message text sent to us by Sentry-go Dim strFile ' Temporary holding file Dim objMessage ' Object reference Dim lngSMTPServerPort ' Port number Dim blnResult ' True/False result Dim blnTriggerResponse ' True/False to run the response Dim intResult ' Result Dim intCount ' Counter Dim intTimeIntervalInSecs ' Holds the time interval we're checking for (in seconds) Dim intResponseIntervalInSecs ' Do not re-run response if alert triggered within this no. seconds ' ****************************************************************************** ' ' TODO: Change the parameters between the "<>" below for your own installation ' Also edit the title & message text as required. To check VBScript syntax ' simply run the script directly from Explorer to check for Syntax errors ' etc. when complete. ' ' ****************************************************************************** ' ------ Determine Whether Action Required ------ ' Set up parameters strSMTPServer = "TODO: Enter your e-mail (SMTP) server name here" lngSMTPServerPort = cDefaultSMTPPort strSender = "TODO: Enter a suitable sending e-mail address - e.g. Sentry-go@" strRecipient = "TODO: Enter the recipient e-mail address here" strTitle = "Sentry-go detected error on server <$$SERVER>" strMessage = "The following error was detected on server <$$SERVER> at <$$TIMELOGGED>. " & vbCRLF & vbCRLF & "Check: <$$TEST>" & vbCRLF & "Error: <$$ERROR>" & vbCRLF & "The defined response has been run." strFile = "TODO: Enter a valid full path/filename here" intTimeIntervalInSecs = TODO: Enter the time interval that will cause the response to be triggered if the appropriate no. errors occur intResponseIntervalInSecs = TODO: Enter the time after which the response will not be re-run ' First determine whether this is an error we're interested in strDetectedErrorMessage = "<$$ERROR>" intResult = InStr (strDetectedErrorMessage, "TODO: Enter the text you wish to search for in the error message - e.g. 6061") If intResult = 0 Then ' Nothing to do WScript.Echo "OK. Inbound event would not cause response to trigger" WScript.Quit (0) End If ' Get the current time strTimeNow = CStr(Now()) ' Read in any existing entries in the file. This will only exist if the ' script has been run before blnResult = LoadFile (strFile) If blnResult = False Then ' There's no file, so log the first entry WScript.Echo "OK. No action required, no current file" AddToFile strFile, strAlertTime, strLoggedTimes, strTimeNow WScript.Quit(0) End If ' ------ See if we need to take action ------ ' If we don't have the correct no. of entries in the file, we don't perform ' any action If Len(strLoggedTimes(cMAX_ENTRIES - 1)) = 0 Then ' Simply append to the file WScript.Echo "OK. No action required, insufficient entries recorded" AddToFile strFile, strAlertTime, strLoggedTimes, strTimeNow WScript.Quit(0) End If ' We do this by checking the 1st entry in our array & comparing that ' with the current time If Len(strLoggedTimes(0)) = 0 Then ' Can't have a value yet WScript.Echo "OK. No action required, insufficient entries recorded" AddToFile strFile, strAlertTime, strLoggedTimes, strTimeNow WScript.Quit(0) End If ' Check the interval intMinutes = DateDiff ("s", strLoggedTimes(0), strTimeNow) If intMinutes < intTimeIntervalInSecs Then ' Check to see if we've already triggered the response in the last minute. If we ' have, then there's no point doing it again If Len(strAlertTime) > 0 Then intMinutes = DateDiff("s", strAlertTime, strTimeNow) If intMinutes < intResponseIntervalInSecs Then ' Assume action already taken. log then quit WScript.Echo "OK. No action required, response already run" AddToFile strFile, strAlertTime, strLoggedTimes, strTimeNow WScript.Quit(0) End If End if ' Trigger alert - clear the file except for the latest entry For intCount = 0 To (cMAX_ENTRIES - 1) strLoggedTimes(intCount) = "" Next ' Record latest times, included latest alert time strAlertTime = strTimeNow AddToFile strFile, strAlertTime, strLoggedTimes, strTimeNow Else ' No action to take, simply note the time, then quit WScript.Echo "OK. No action required, times not within specified interval" AddToFile strFile, strAlertTime, strLoggedTimes, strTimeNow WScript.Quit(0) End If ' ------ Take defined action ------ ' ' Access the shell WScript.Echo "Triggering response/action" Err.Clear Set objShell = CreateObject("WScript.Shell") If Err.Number <> 0 Then ' Error WScript.Echo "Error. Unable to create the shell object. " & Err.Description WScript.Quit(1) End If ' Stop/start the service & wait - TODO: Enter your command here objShell.Run "NET STOP ""Print Spooler""", cHIDE, true If Err.Number <> 0 Then ' Error WScript.Echo "Error. Unable to execute requested command. " & Err.Description WScript.Quit(1) End If ' TODO: Enter another command here (or delete etc.) objShell.Run "NET START ""Print Spooler""", cHIDE, true If Err.Number <> 0 Then ' Error WScript.Echo "Error. Unable to execute the START command. " & Err.Description WScript.Quit(1) End If ' Cleanup Set objShell = Nothing ' ------ Send E-mail to notify Administrators ------ ' TODO: Delete this code (from here down to "####END OF EMAIL CODE####" if you don't ' want a notification to be sent) WScript.Echo "Sending notification of response/action" ' Connect to CDO for messaging logic Set objMessage = CreateObject("CDO.Message") If Err.Number <> 0 Then ' Error WScript.Echo "Error. Unable to create the CDO.Message object. " & Err.Description WScript.Quit(1) End If objMessage.From = strSender objMessage.To = strRecipient objMessage.Subject = strTitle objMessage.TextBody = strMessage ' Configure the message & transport objMessage.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2 objMessage.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/smtpserver") = strSMTPServer objMessage.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = lngSMTPServerPort objMessage.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/smtpconnectiontimeout") = 60 objMessage.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/smtpusessl") = False ' Update the configuration objMessage.Configuration.Fields.Update If Err.Number <> 0 Then ' Error Set objMessage = Nothing WScript.Echo "Error. Unable to update the message configuration. " & Err.Description WScript.Quit(1) End If ' Now send the messasge objMessage.Send ' Check we managed to send If Err.Number <> 0 Then ' Error Set objMessage = Nothing WScript.Echo "Error. Unable to send the message. " & Err.Description WScript.Quit(1) End If ' ------ Cleanup ------ Set objMessage = Nothing ' "####END OF EMAIL CODE####" WScript.Echo "OK. Unable to send the message. " & Err.Description WScript.Quit (0) ' ------ End of Script ------ ' ********************************************************************* ' Load the file ' ********************************************************************* Function LoadFile (ByVal strFile) On Error Resume Next Dim objFSO Dim objFile Dim intCount ' Access the file Set objFSO = CreateObject("Scripting.FileSystemObject") If Err.Number <> 0 Then ' Error WScript.Echo "Unable to create the file system object. " & Err.Description WScript.Quit(1) End If ' Attempt to open the file Set objFile = objFSO.OpenTextFile(strFile, cREADFILE, False) If Err.Number <> 0 Then ' Assume no file Set objFile = Nothing Set objFSO = Nothing LoadFile = False Exit Function End If ' Read in each line in turn into the array. The first entry is the last ' time the response was run, if it begins with "Alert=" while Not objFile.AtEndOfStream strEntry = objFile.ReadLine() If Len(strEntry) > 0 Then ' Check for an alert time If Left (strEntry, 6) = "Alert=" Then ' Save the alert time strAlertTime = Right (strEntry, Len(strEntry) - 6) Else ' Save the logged time strLoggedTimes (intCount) = strEntry intCount = intCount + 1 End If End If Wend ' Close the file objFile.Close Set objFile = Nothing LoadFile = True End Function ' ********************************************************************* ' Write out our array of dates/times to the file ' ********************************************************************* Function AddToFile (ByVal strFile, ByVal strAlertTime, ByVal strLoggedTimes(), ByVal strTimeNow) On Error Resume Next Dim objFSO Dim objFile Dim intCount Dim intStart ' Access the file Set objFSO = CreateObject("Scripting.FileSystemObject") If Err.Number <> 0 Then ' Error WScript.Echo "Unable to create the file system object. " & Err.Description WScript.Quit(1) End If ' Attempt to open the file (this will also delete the existing file) Set objFile = objFSO.OpenTextFile(strFile, cWRITEFILE, true) If Err.Number <> 0 Then WScript.Echo "Unable to create (overwrite) the file " & strFile & ". " & Err.Description Set objFSO = Nothing WScript.Quit(1) End If ' If we don't have the full number of entries, simply add the latest ' time to the file If strLoggedTimes(cMAX_ENTRIES - 1) = "" Then intStart = 0 Else ' We will ignore the 1st entry intStart = 1 End If ' First write out the latest alert time objFile.WriteLine "Alert=" & strAlertTime ' Write out the details, ignoring the earliest entry For intCount = intStart To (cMAX_ENTRIES - 1) If strLoggedTimes(intCount) <> "" Then objFile.WriteLine strLoggedTimes(intCount) End If Next ' Now log the latest time objFile.WriteLine strTimeNow ' Close the file objFile.Close Set objFile = Nothing AddToFile = True End Function