Task Scheduler Error Alerting

One of the worst things about Task Scheduler is not knowing when tasks fail. Well, as it it turns out, you can have Task Scheduler take actions, like run a powershell script to email you, when triggered by certain events in the event viewer. By default, you can get it to trigger on very generic things like Success and Failure based on Event ID. But what if you want to trigger based on Result Codes? That’s a bit tougher because that’s all in the XML view, and not part of what Event Viewer actually knows how to work with. Thankfully, you can build an XML query manually.

So! In my example use case, I am running a batch file. When it succeeds without issues, it’ll give event id 201 and result code 0, but when it fails, it could fail with a bunch of different codes, including 2147942401 and 2147942402. Well, I don’t really care how it failed, just that it did, so I want to be alerted when event id 201 has anything in the result code that isn’t 0.

Go ahead and make a New Task. Begin the Task “On an event”. Click the “Custom” radio button. Edit the Event Filter and go to the XML tab. Make sure the “Edit query manually” checkbox is checked. Then, include the following:

<QueryList>
  <Query Id="0" Path="Microsoft-Windows-TaskScheduler/Operational">
    <Select Path="Microsoft-Windows-TaskScheduler/Operational">*[System[(Level=1  or Level=2 or Level=3 or Level=4 or Level=0 or Level=5) and (EventID=201)]]</Select>
    <Suppress Path="Microsoft-Windows-TaskScheduler/Operational">*[System[(Level=1  or Level=2 or Level=3 or Level=4 or Level=0 or Level=5) and (EventID=201)]] and *[EventData[Data[@Name='ResultCode'] and (Data="0")]]</Suppress>
  </Query>
</QueryList>

Let’s walk through this and break it down a bit.

<Query Id="0" Path="Microsoft-Windows-TaskScheduler/Operational"> 

Just points to the path in Event Viewer. You can cheat this by using the Filter tab to fill out everything it allows you to before switching to the XML tab and editing the query manually. You won’t be able to switch back and forth, though, once you’ve started editing.

<Select Path="Microsoft-Windows-TaskScheduler/Operational">*[System[(Level=1  or Level=2 or Level=3 or Level=4 or Level=0 or Level=5) and (EventID=201)]]</Select>

This says to get all events that have Event ID 201 and match all of those different alert levels (I just chose all of them). “But wait!” I hear you saying “I want to be more selective about the result code, don’t I?” Yup, which is why:

<Suppress Path="Microsoft-Windows-TaskScheduler/Operational">*[System[(Level=1  or Level=2 or Level=3 or Level=4 or Level=0 or Level=5) and (EventID=201)]] and *[EventData[Data[@Name='ResultCode'] and (Data="0")]]</Suppress>

This means “Don’t tell me about anything with Result Code 0.” Anything else means something happened and I need to go fix something.

So, “Tell me about every Event ID 201 event, unless it has Result Code 0.” Simple.