4
votes

I am trying to create a Windows Scheduled Task to notify my everytime some other scheduled task in a special folder failed. To do this I have setup a scheduled task to run with a trigger 'On an event' using a Custom event filter.

I want to carry out some action (send an email) when the result code of a scheduled task is NOT 0 (i.e. The task failed). To do this I have setup the following as my custom XML/XPath:

<QueryList>
    <Query Id="0" Path="Microsoft-Windows-TaskScheduler/Operational">
        <Select Path="Microsoft-Windows-TaskScheduler/Operational">*[System[(EventID=201)]] and *[EventData[(Data[@Name="ResultCode"]!=0)]]</Select>
    </Query>
</QueryList>

The *[System[(EventID=201)]] checks to see if the EventID of the event log was 201 (Action completed).

The *[EventData[(Data[@Name="ResultCode"]!=0)]] checks to see if the result code was NOT 0 (Failure)

Now Here is my setup. I have a subset of scheduled tasks in a sub-folder under the Windows Task Scheduler:

 -> Task Scheduler
     -> Task Scheduler Library
         -> XYZ
             -> Task 1
             -> Task 2
             -> ...

I only want my new notification task to notify me for failures of tasks under this \XYZ\ sub-folder.

Here is an example XML output from the Windows Event logs that will have the task name \XYZ\TaskNameHere

<Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
    <System>
        <Provider Name="Microsoft-Windows-TaskScheduler" Guid="{de7b24ea-73c8-4a09-985d-5bdadcfa9017}" />
        <EventID>201</EventID>
        <Version>0</Version>
        <Level>4</Level>
        <Task>201</Task>
        <Opcode>2</Opcode>
        <Keywords>0x8000000000000000</Keywords>
        <TimeCreated SystemTime="2012-04-02T13:51:41.708Z" />
        <EventRecordID>385206</EventRecordID>
        <Correlation ActivityID="{EC12AB2E-C049-4AF5-9FAB-4540F2B3AD83}" />
        <Execution ProcessID="2580" ThreadID="4960" />
        <Channel>Microsoft-Windows-TaskScheduler/Operational</Channel>
        <Computer>[email protected]</Computer>
        <Security UserID="S-1-5-18" />
    </System>
    <EventData Name="ActionSuccess">
        <Data Name="TaskName">\XYZ\Task Name Here</Data>
        <Data Name="TaskInstanceId">{EC12AB2E-C049-4AF5-9FAB-4540F2B3AD83}</Data>
        <Data Name="ActionName">C:\SomeProgram.exe</Data>
        <Data Name="ResultCode">3762504530</Data>
    </EventData>
</Event>

Here is the XPath I have tried but it does not work and gives me a parse error.

<Select Path="Microsoft-Windows-TaskScheduler/Operational">*[System[(EventID=201)]] and *[EventData[(Data[@Name="ResultCode"]!=0)]] and *[EventData[(Data[@Name="TaskName" and contains(text(),'\XYZ\')])]]</Select>

Any ideas?

3
I tried your XPath on the provided XML, it's structurally sound and returned "True". Are you scheduling these tasks based on it returning 1 or 0, and not True/False? You could add a number() wrap to the xpath if so.JWiley
If my XPath returns true that is the EventID=201 and the ResultCode != 0 and the TaskName starts with \XYZ\ then I want to send an emailChris Sansone
Right, and I'm saying I don't believe it is your XPath, because what you have is returning True already for the given XML. So I'm thinking it has to do with something else, possibly the value you're checking in order to create the event.JWiley
Here is what I get when I try to use the above. i43.tinypic.com/24qq0yq.jpgChris Sansone

3 Answers

4
votes

Just in case anyone was wondering this answered my question:

http://msdn.microsoft.com/en-us/library/cc231312%28v=prot.10%29.aspx

It turns out the Task Scheduler does not implement the entire XPath functionality, only a subset of it.

2
votes

This query works fine in Windows 10 Task Scheduler. It listens for my-task being completed (EventID=201) and checks the ResultCode. I have two tasks listening to different result codes of another task: =0 for informing the user by a powershell messagebox that the task completed successfully and !=0 to report an error.

<QueryList>
    <Query Id="0" Path="Microsoft-Windows-TaskScheduler/Operational">
        <Select Path="Microsoft-Windows-TaskScheduler/Operational">
*[System/EventID=201[EventData[Data[@Name='ResultCode']=0][Data[@Name='TaskName']='\my-task']]
    </Select>
</Query>
</QueryList>
0
votes

I think this can be achieved with the following snippet.

    string queryString = "*[System/EventID=201] and *[EventData[(Data[@Name=\"ResultCode\"]=0)]]"; ;
    var query = new EventLogQuery("Microsoft-Windows-TaskScheduler/Operational", PathType.LogName, queryString);
   var reader = new EventLogReader(query);
//read...
   var eventRec = reader.ReadEvent();