Running a Scheduled Task after another


Within the Windows Task Scheduler it is possible to fire off processes based on a lot of different triggers, both time based, and windows event based. However it seemed quite hard to fire off one scheduled task after another had completed, despite there being an event log showing the task starting, running and completing:clip_image002[4]

The main reason for running one Scheduled Task after another was due to the change in user running the task, so they could not be chained as the same task.

The following example is much more simplified, but the underlying solution is the same.

I have created a very simple Ping Task which displays a message, and wanted to chain a Pong task to run directly after this has completed. Creating the tasks are quite simple, but now I want to set a trigger on Pong for when the Ping task completes. This proved a little more difficult, though “On Event” appeared to be the right way to go, as the Task Scheduler outputs events at all points in the operation of a Task.

The most interesting one to me was the “Task Completed” event you can see above. Looking at XML view within the details of this event it appeared that I knew all the EventData I needed to know to run the Pong task on:

clip_image004[4]

The trouble was with the Basic On an event trigger, you could only specify the Event ID which is 102 for all Task completed events on all Tasks, and not just my Ping Task:

clip_image006[4]

However it is possible to define a Custom Event, though the standard filter does not allow much control over the selection of the events:

clip_image008[4]

Using this as a starting point, and selecting the most that I could in this dialogue also started to populate the custom XML XPath, which would allow far more control.

clip_image010[4] clip_image012[4]

Now to start writing the XPath and refering to the XML from the TaskCompleted Event:

<Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
   <System>
      <Provider Name="Microsoft-Windows-TaskScheduler" Guid="{DE7B24EA-73C8-4A09-985D-5BDADCFA9017}" />
      <EventID>102</EventID>
      <Version>0</Version>
      <Level>4</Level>
      <Task>102</Task>
      <Opcode>2</Opcode>
      <Keywords>0x8000000000000001</Keywords>
      <TimeCreated SystemTime="2011-10-25T16:20:39.200166100Z" />
      <EventRecordID>109987</EventRecordID>
      <Correlation ActivityID="{13A3621A-839B-4FCD-83F3-B6677F1EC9F2}" />
      <Execution ProcessID="9372" ThreadID="8744" />
      <Channel>Microsoft-Windows-TaskScheduler/Operational</Channel>
   </System>
   <EventData Name="TaskSuccessEvent">
      <Data Name="TaskName">\Ping</Data>
      <Data Name="InstanceId">{13A3621A-839B-4FCD-83F3-B6677F1EC9F2}</Data>
   </EventData>
</Event>

 

I could use an XPath to get the Data element with TaskName of \Ping:

<QueryList>
   <Query Id="0" Path="Microsoft-Windows-TaskScheduler/Operational">
      <Select Path="Microsoft-Windows-TaskScheduler/Operational">*[EventData
[@Name='TaskSuccessEvent'][Data[@Name='TaskName']='\Ping']]</Select>
   </Query>
</QueryList>
 

clip_image014[4]

By adding this trigger, and firing the Ping Event, the Pong Task Fires immediately after the Ping is complete.

Breaking the XPath down further:

clip_image001

It is now a simple case of reusing this XPath replacing the Task Name, \Ping here, with the task to run after.

Comments (16)

  1. chrismec says:

    Thanks!!! Was struggling on the event data syntax. You have helped me tremendously!!!

  2. Hi Dave, lets say that under the task scheduler library I have a folder named 'XYZ' and I want to start another task ONLY when any of the tasks under this 'XYZ' folder complete. What would the XPath look like?

  3. DaveT2 says:

    Hi Chris,

    Looking at the event details the taskname would be 'XYZ' followed by your event name.  I believe there is a starts-with function within xpath, however I cannot get that to work on my side, the way you could get this working is to use multiple triggers with the xpath [EventData [@Name='TaskSuccessEvent'][Data[@Name='TaskName']='XYZ{your task name here}'] for each events under that folder replacing {your task name here} with each task name in that folder.

    Hope that helps.

    Dave

  4. Chris says:

    Hi Dave,

    Thanks for your reply. I was hoping to make a generic filter for any task under the XYZ folder but it looks like thats not possible. Does the Windows Task Scheduler not allow certain functions such as contains, or starts-with?

  5. Damodar says:

    Thank you for posting this. This was very useful.

  6. Chris says:

    Hello,

    i've another question. Is it possible to start Pong depending on Success of Ping and not before! a specified  time (like ping ends 4 p.m. but Pong shouldn't start before 8 p.m.)? The problem is, that the job has to run every day. Many thanks in advance.

    Greats Chris

  7. Dhanya says:

    Hi Dave,

    Thank you..

    My task is working by using your tips.

  8. Martin K. says:

    A wonderful post!  I expected I would be searching for hours and having to figure out the XML syntax all on my own.  This will save me sooooo much time in doing essentially what you needed to get done.

  9. Mr. chas says:

    Thank you so much for your best clarification

    now I can mange run task one after the other

    10Q again

  10. Amit Bhatt says:

    What if the Task is completed with Exit code other than 0. I want my next task to be started only if the forst one completed with Exit code 0.

    Thanks.

  11. Ced says:

    Hi, thanks for this post, it helped me a lot !

    I've gone further by adding the condition "executing a task only if the previous was completed with the exit code 0".

    In order to do that, the "Action completed" event is better than the "task completed" one. The Event Data element of this "Action completed" event contains one more child element with the name "ResultCode" which is exactly what we are looking for !

    So the xPath is :

    *[EventData[@Name='ActionSuccess'][Data[@Name='TaskName']='Ping'][Data[@Name='ResultCode']='0']]

    Hope that help some of you

    Ced

  12. Anthony Genovese says:

    Thanks for your help!

    I have a question on how you would extend this out in the following scenario.  I have 4 tasks, A, B, C, D. I want to trigger task D based on A, B, and C tasks all succeeding.  What would the XPATH look like in that scenario.

  13. JW0914 says:

    Just wanted to say thanks! =]  

    It's nigh impossible to find the information in your blog on TechNet, unless someone knew exactly what they were looking for, so thank you 🙂

  14. Francis says:

    Hi Dave,

    Is it possible add a date filter to it. Like I would like to know the status of the Task which got completed in the last 7hrs. Then it will trigger the new task ?

    Francis.

  15. Ana says:

    Hello

    I have 3 tasks, A, B and C. My task C just run when task A and B completed. How I do? It's possible?

Skip to main content