
I am loooking for a way to monitor and display each of my Windows Servers scheduled tasks within Orion on the Server node page. Is there way to do this and then be alerted if a new task is created or fails.
I am not sure APM or the new version SAM can do this or Orion or LEM for that matter.
Anyone that can point me in the right direction or create a Context Exchange script or monitor I would be greatly appreciative.
I have opened a ticket on this Case #310538. Have not heard anything from support as of yet on this.
C:\Windows\Tasks contains the Windows Task scheduler items, so you should be able to monitor that folder to check for the addition of any new tasks.
There is also a log file at C:\Windows\SchedLgU.txt for scheduled tasks. Refer to How to troubleshoot scheduled tasks in Windows XP and in Windows Server 2003 for some additional information on this log file. You should also check out the 'schtasks' command which will provide a text response that can be parsed.
From the above items you should be able to put together a few scripts that will grab whatever information you want.
Thanks much but now how do I get the below item to display on the server node page? That is what I would like to see and this is beyond me to figure out how to get that to where it would be availble on the server node page in Orion.
"You should also check out the 'schtasks' command which will provide a text response that can be parsed"
You'd need to create a new template with a Windows Script component. With VBScript you should be able to use wshshell.exec to run the schtasks command. I haven't played around with the command itself too much, but it looks like you should be able to run a query against one particular task. Once you have the response you can use VBScript's string and/or regular expression functions to grab the status code and last run date/time.
Once the template is created just add it to the node. If you want multiple tasks monitored you can either duplicate the component inside the template or make copies of the template.
Does that clear things up for you?
All the way up until you mentioned me creating the script with VBScript, it all made sense to that point.
Sorry but when mentioning scripting I lock up and can't do it or takes me forever to get anything that works. A big area that I am not comfortable doing or attempting unless it is just changing someone else's scripts but creating them from scratch not going to be able to do it not even sure where to start on that.
If it is too much to ask for someone out here to take care of creating that piece than I will not be able to do this.
Thanks much for anyone wanting to create this!!!
I spent some time working on this, but its looking more and more like we won't be able to pull meaningful data from remote computers without some creative temp files.
So far I've found that there is a WMI object Win32_ScheduledJob, but this only includes tasks that were created using WMI and does not include information about tasks that were created manually using the "Add Scheduled Task" wizard (or even information about tasks created with WMI then later modified through the GUI). On a side note, this object does allow for the creation of scheduled tasks and maybe the folks in charge of the unmanage utility could incorporate this to make scheduling unmanage windows a less manual process.
Moving on I attempted to run the schtasks, but unfortunately Windows scripts run locally on the Solarwinds box (as opposed to the Linux scripts which run on the remote box). I do have a script right now that can be used to monitor scheduled tasks on the Solarwinds server and seems to be working just fine. The only problem is that if you attach it to another node it is still only retrieving information from the Solarwinds server itself. Even using the command line switches that allow for pulling data from a remote computer don't seem to be returning meaningful data.
The last idea I had was to parse the SchedLgU.txt log file, but I found that the log flie overwrites entries once it reaches a certain size. This will cause all sorts of zany behavior if you have a lot of tasks or even if you just have a few tasks that run weekly and one or two that run more frequently.
If I have some downtime today I'll play around a bit with running a remote script on the target computer then writing to a tmp file and having Solarwinds read the contents of the tmp file. This may or may not work out too well.
Its very unfortunate because the WMI object is the best tool to use for this, but Microsoft in its infinite wisdom decided to make it all but useless for data gathering.
Update: It appears that Vista/Server 2008 and above have a Schedule.Service object that could be leveraged to provide details of all scheduled tasks. All of our Windows servers are 2k3, so I'm not able to work with this myself. This would also only be limited to those environments that are running Solarwinds on 2k8+ servers. Going to keep playing with running the script remotely and see what I can come up with.
This turned out to be one of the funnest things I've ever done with VBScript.
This was created for APM 4.2 - Unfortunately I don't have access to a pre-4.2 installation to test. If you want to test on APM prior to 4.2 you'll need to change all of the lines that show "Message.Task" and "Statistic.Task" to just show "Message" and "Statistic". Also, I was only able to test from a 2k3 server to a 2k3 server.
A few caveats about this. 2 changes might need to be made in order to get this working. The first revolves around WSH 5.6 having a bug that prevents remote execution of scripts. This is likely the default WSH version on a 2k3 server. You can check the current WSH version on both the Solarwinds box and the remote box by running the command "cscript" at a command prompt. One of the staffers should be able to verify if installing WSH 5.7 will cause any problems, but I don't think it will. If you test and get an error message saying "Execution of Windows Script Host failed" then this is likely the cause.
The second change is a registry tweak that will allow the local computer to run a script on the remote computer:
Go to HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Script Host\Settings
Add String Value named "Remote" and set the value to "1".
I can't speak to security implications as a result of that change, so you'll want to do it at your own risk.
On to the script!
Command line should read as follows:
${IP} "taskname"${IP} will pull the IP address of the target node, so you won't need to fill that out manually.
taskname needs to be the full name of the scheduled task. It needs to be inside double quotes and is case sensitive.
And the script body itself...
'Requires WSH 5.7
'Create script as string
Set lstArgs = WScript.Arguments
If lstArgs.Count = 2 Then
remoteComputer = Trim( lstArgs(0))
taskName = Trim( lstArgs( 1 ))
Else
WScript.Echo "Message.Task: Usage: cscript.exe chckSchedTaskForFail.vbs [fullTaskName]" _
&vbCRLF &" [fullTaskName] Full name of task excluding .job extenstion"
WScript.Echo "Statistic.Task: 0"
WScript.Quit( FAIL )
End If
strScript = _
"Const FAIL = 1, SUCCESS = 0" & vbCRLF & _
"Dim taskName" & vbCRLF & _
"Dim strCommand, strStatus, strTask" & vbCRLF & _
"Dim arTask" & vbCRLF & _
"Dim wshObj, exec" & vbCRLF & _
"Dim re, strDelimiter" & vbCRLF & _
"Set lstArgs = WScript.Arguments" & vbCRLF & _
"If lstArgs.Count = 1 Then" & vbCRLF & _
"taskName = Trim( lstArgs( 0 ))" & vbCRLF & _
"Else" & vbCRLF & _
"Err.Description = ""ArgumentError""" & vbCRLF & _
"Err.Raise vbObjectError + 1" & vbCRLF & _
"End If" & vbCRLF & _
"strCommand = ""schtasks /query /NH /fo CSV""" & vbCRLF & _
"strDelimiter = """""",""""""" & vbCRLF & _
"' Set up regex parser for use later" & vbCRLF & _
"Set re = new regexp" & vbCRLF & _
"re.IgnoreCase = False" & vbCRLF & _
"re.Pattern = taskName" & vbCRLF & _
"Set wshObj = WScript.CreateObject(""WScript.Shell"") " & vbCRLF & _
"Set exec = wshObj.Exec(strCommand) " & vbCRLF & _
"Do While Not exec.StdOut.AtEndOfStream" & vbCRLF & _
"strText = exec.StdOut.Readline()" & vbCRLF & _
"'Test the line for the taskName" & vbCRLF & _
"If re.test(strText) Then" & vbCRLF & _
"arTask = split(strText, strDelimiter)" & vbCRLF & _
"'Additional test to verify full task name match" & vbCRLF & _
"If arTask(0) = chr(34) & taskName Then" & vbCRLF & _
"strTask = strText" & vbCRLF & _
"strStatus = arTask(2)" & vbCRLF & _
"Exit Do" & vbCRLF & _
"End If" & vbCRLF & _
"End If" & vbCRLF & _
"Loop" & vbCRLF & _
"'If the task isn't found at all" & vbCRLF & _
"If strTask = """" Then" & vbCRLF & _
"Err.Description = ""TaskNotFound""" & vbCRLF & _
"Err.Raise vbObjectError + 1" & vbCRLF & _
"End If" & vbCRLF & _
"re.Pattern = ""Running""" & vbCRLF & _
"re.IgnoreCase = True" & vbCRLF & _
"'If the status is either blank or ""Running""" & vbCRLF & _
"If strStatus = chr(34) or re.test(strStatus) Then" & vbCRLF & _
"Err.Description = ""NoErrors""" & vbCRLF & _
"Err.Raise vbObjectError + 1" & vbCRLF & _
"End If" & vbCRLF & _
"'If the status is anything else" & vbCRLF & _
"Err.Description = strStatus" & vbCRLF & _
"Err.Raise vbObjectError + 1"
'Create Script as Local temp file
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set tmpFolder = objFSO.GetSpecialFolder(2)
'Have to use C:\ instead of dynamically generated temp tmpFolder
'Due to issues with spaces in path
sFilePath = "C:\" & Replace(objFSO.GetTempName,"tmp","vbs")
Set objTextFile = objFSO.CreateTextFile(sFilePath,True)
objTextFile.Write strScript
objTextFile.Close
'Call script using WSHController.CreateScript
Set Controller = WScript.CreateObject("WSHController")
Set RemoteScript = Controller.CreateScript(sFilePath & " " & taskName, remoteComputer)
RemoteScript.Execute
'Wait for remote script to complete
Do While RemoteScript.Status <> 2
WScript.Sleep 100
Loop
'Second script uses errors to return information
Set Response = RemoteScript.Error
' Clean up local temp file
Set objTextFile = objFSO.GetFile(sFilePath)
objTextFile.Delete
If Response.Description = "ArgumentError" Then
WScript.Echo "Message.Task: Usage: Controller.CreateScript([script],[task])" & vbCRLF & _
"[script] Full path to script to be run on remote computer" & vbCRLF & _
"[task] Full name of task to be checked - Case Sensitive"
WScript.Echo "Statistic.Task: 0"
WScript.Quit(FAIL)
ElseIf Response.Description = "TaskNotFound" Then
WScript.Echo "Message.Task: Task " & taskName & " Not Found"
WScript.Echo "Statistic.Task: 0"
WScript.Quit(FAIL)
ElseIf Response.Description = "NoErrors" Then
WScript.Echo "Message.Task: No Errors"
WScript.Echo "Statistic.Task: 0"
WScript.Quit(SUCCESS)
Else
WScript.Echo "Message.Task: Task " & taskName & "Failed with Error: " & Response.Description
WScript.Echo "Statistic.Task: 1"
WScript.Quit(FAIL)
End IfThis will show the component as Up if there are no errors with the script and Down otherwise. Also a 0 statistic will be returned as long as the task itself didn't fail with an error (bad command line, or missing tasks will show statistic 0), but a 1 statistic will be returned for any errors with the task itself.
I also attached the template as a .txt file. You should be able to change the extension to .apm-template and apply it. Once someone has verified that they can get it working I'll post it up on the Content Exchange.
The below is mostly a theoretical discussion about the way the script works... mostly intended for APM staffers and any other Script Gurus out there
The biggest problem faced here was the inability of Windows to run a remote script similar to how the Linux scripts work.
This script basically works by creating another script as a temp file on C:\, sending the script to a remote computer where it runs. In this case I created a script which works well locally and converted it to a giant string inside the script - The script could also be pre-generated in a file someone, but I wanted to have everything self contained in the APM Template.
Due to the vagaries of VBScript and WSH, return messages are sent back by throwing errors with set descriptions. The original script then reads the error message, deletes the locally created temp file, and parses the response to determine the proper Message and Statistic values to report to Solarwinds. In this case I used keywords that were parsed by the original script because I chose to have the component show Down unless there were no errors, but the description could be setup as a full Message/Statistic:
Err.Description = "Message.Task: SomeMessage" & vbCRLF & "Statistic.Task: 1"
Then the original script would only need to echo the Response.Description instead of parsing.
I mention this because if this could be implemented into the APM code it could open up quite a few new possibilities for monitoring that aren't currently available. Granted there is a lot of information available through WMI, but just like with the Scheduled Tasks WMI may not always be sufficient to gather necessary information (third party applications come to mind).