3

When one scheduled task is completed, I want another task to start immediately after. Task #1 already has 32 actions, so I cannot add another action. So I figured "Oh, I'll just split my single task up into multiple tasks and link them together" But then how do I trigger task #2 to only start (and always start) when task #1 ends?

I was quite surprised that something like this is unavailable and/or is unintuitive in the Task Scheduler.

4
  • 2
    Its much easier to create a batch script and run that one script. The batch script would then execute all tasks in order one after another. You are not limited by any amount then.
    – LPChip
    Commented Aug 6, 2022 at 18:49
  • Editing a single file would have its benefits. But what happens if a task fails in the batch script? how would you know which task failed? How do you run the .bat or .cmd without a CMD window showing up? How do you log the execution of each "task" in the batch and the result? @LPChip
    – Jon Grah
    Commented Aug 7, 2022 at 5:08
  • batch scripts can write to a log file, and each command will produce an ERRORLEVEL code after execution, stating if it was succesful or not, which you can log. A batch file will carry on its instructions even after a failure unless you program a halt in it. ERRORLEVEL 0 is a succesful, anything higher is usally a warning or error. See also: ss64.com/nt/errorlevel.html
    – LPChip
    Commented Aug 7, 2022 at 10:42
  • How do you ensure that the CMD run in task scheduler; scheduler waits until the .CMD finishes? When I use nircmd, it reports the task is successful immediately and is completed. I want it to wait until CMD is done before scheduler says task is complete. @LPChip edit: SilentCMD has task scheduler wait until the .CMD is exited before reporting completion.
    – Jon Grah
    Commented Aug 17, 2022 at 21:46

2 Answers 2

1

I decided to create CMD script and just stick all my sequential commands there. Then just run that CMD file in Task Scheduler as a single action. I just echo my own custom logs after each command along with timestamp so that I can follow the progress. I still don't know how to print the ERRORLEVEL codes. In addition to having unlimited actions, I can add comments for each action which I couldn't do with task scheduler actions.

To run silently (without CMD console window), you can use nircmd or silentCMD script.

I still left the original answer below as it might help someone who wants to work exclusively with Task Scheduler. Or needs to figure out how to implement event-based triggering.


After searching exhaustively, I found a blog post that figured this out quite some time ago. So I will copy it here, with updated steps that are easier to follow along. Basically you have 3 options:

  1. If your taskX has <= 32 actions, just add a new action to the taskX If your taskX has > 32 actions, then you must either
  2. split taskX into multiple task, and set each subsequent task to run sequentially after the previous task completes [shown below]
  3. use 3rd party software like z-cron

Splitting up tasks and running them tasks sequentially

Whether you reached the 32 action limit in your taskX or simply want to organize some actions into different tasks, the secret to getting them to run one after the other is to have taskX+1 set with an custom event trigger that scans specific event logs and looks for event 102 Task Completed from a specific task (the previous task in sequence, or taskX in this case).

  1. First we need to setup taskX if you have not done so already with all the actions that you need for that task. And run taskX at least 1 time successfully. My taskX is called Ping in the screenshot. Then look at the history log, which should have event 102 sorted at the top. You can select event details from the right-click context menu. event details context menu
  2. Click on Details Tab and select XML View. You are looking to extract 4 tag/attributes:

Provider-Name: Microsoft-Windows-TaskScheduler
EventID: 102
Channel: Microsoft-Windows-TaskScheduler/Operational
TaskName: \Ping
] TaskName: is the most important one
Details - XML view
3. Setup TaskX+1 (I will call Pinging #2). The important thing is the trigger, which will only be based on an event.
New Trigger - on an event
4. The event has to be custom defined. You can skip to the next step for the final code to be copy/pasted.
* After selecting custom radio and New Event Filter, select radio by source and Select TaskScheduler Event Source. Event Logs will prepopulate with some event log types. * Go to Event logs dropdown and uncheck all other logs except for Microsoft-Windows-TaskScheduler/Operational. Below Screenshot will hopefully clarify things custom event filters * switch to XML tab and you will see something like this

<QueryList>
  <Query Id="0" Path="Microsoft-Windows-TaskScheduler/Operational">
    <Select Path="Microsoft-Windows-TaskScheduler/Operational">*[System[Provider[@Name='Microsoft-Windows-TaskScheduler']]]</Select>
  </Query>
</QueryList>

5. On the XML tab, You will check Edit query manually and will answer yes to the warning prompt. So the XML can be blank, it doesn't matter at this point as you will manually edit or copy the full code from here.

Filter XML sample + edit query manually dialog box

*[System[Provider[@Name='Microsoft-Windows-TaskScheduler']]] will be edited to become
*[EventData[@Name='TaskSuccessEvent'][Data[@Name='TaskName']='\Ping']]

the final code will look like this

<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>

XML Filter Final pasted code

make sure to Ok all of the changes back to the Task Scheduler main window.

  1. Test to see if this works. Run TaskX and when it completes fully, TaskX+1 should immediately begin running.

Troubleshooting

Mine has worked on windows 10 and Win 2012R2. I assume other Windows versions it should work. If it doesn't work, this is most likely the causes of error:

  1. Double-check the manual query XML to make sure the syntax is exact. Including the type of apostrophe ' or quotes " used.

I would try a simple task with simple action like ping using a cmd file you can edit with notepad++

  1. Make sure the Task Scheduler History is enabled. You would need this anyways to capture the TaskName: shown in the procedure above.
    Make sure Task Scheduler History enabled

  2. Make sure the Task Scheduler Operational Logs are enabled.

Event ViewerApplications and Services LogMicrosoftWindowsTask SchedulerOperational → right-click it, (or go to the right pane) Properties

Operational Logs location from Event Viewer GUI

Make sure the logs are enabled!

Operational Log Properties Window

Last 3 image credits to @beatcracker and his related scheduled task post here.

  1. [unlikely] The programs you are running should complete their task before indicating [to windows OS event log] that the task is finished. This is why just using a batch file alone is insufficient to deal with programs that may have exceptions. In my experience, all my programs actually complete their tasks before terminating the program and reporting to windows that it is finished/exited.

But when using start cmd command, you may want to add /w or /WAIT parameter which will ensure that specific start program launched will wait for the program to finish before moving to the next command / exiting.

Example start /B /w ping -n 1 -w 3000 -l 40 192.168.0.1

Now why Winblows doesn't make this ability to sequentially start tasks (not just actions) very easy for the user to do via GUI (and/or well documented even if the custom xml is needed) is....well....typical Micros**t thinking. Or allow more than 32 actions in a single task? This is windows 10, not windows 95. Anyways, I hope this helps someone.

1

Based on Jon Grah's solution, I have a little add-on.
If you have a directory in the task scheduler, you can reference to it like this.
'\Test\Test1' - that means the directory is Test. And Task name is Test1.

It would look like this in the Custom made trigger:

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

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .