Redundancy for Scheduled Tasks

By Greg 6 comments

Do you use Scheduled Tasks as part of your production environment? Maybe to run those end of month reports for finance, or to run a nightly batch process, to import data from some uploaded flat files, or to download data from an external source on a regular interval. Scheduled Tasks are a really simple way to have Windows kick off a process based on a simple scheduling system.

But what happens if your server goes offline? What happens when you need to patch? What happens when you need to upgrade to the new version of Windows and create all of those tasks again? Scheduled Tasks, like all other processes that are bound to 1 Windows instance, are subject to downtime. How do you avoid that? That’s where Failover Clusters come to play.

Microsoft has had Clusters since NT 4.0, but failover clusters really started taking off in Server 2008 when it became Windows Server Failover Clustering. If you’re not familiar with Failover Clusters, this is not the post for you, start with Microsoft Docs to find out how to create a cluster and so on. For this post, I’m going to assume you have a Failover Cluster up and running with multiple nodes in it.

In a Failover Cluster, you have the ability to create Scheduled Tasks. Windows will coordinate all of the nodes in the cluster to run the Scheduled Task as you have set it up. You have 3 options on where the task should run:

  1. Any Node – this will make sure that it runs once (and only once) on a node. You have no control on which node, just that one of the nodes will do the work. This is great for a job that just needs to run, like sending out the monthly finance reports.
  2. Cluster Wide – this will make sure that it runs on every node in the cluster. This could be great for a maintenance task on the cluster where each node needs to clean up after itself.
  3. Resource Specific – this will look at another resource in the cluster, work out which node it is running on, and run the scheduled task on that node. This is great for a job that needs access to a disk or other resource that is part of the cluster, or as a way to give you some control over which node will run the task.

Setting up a scheduled task can only be done via PowerShell, there is no GUI for this, but it’s not hard (and you should probably be scripting them out anyway, right?) What can be difficult is setting up the trigger for your scheduled task. If you want a task to run each day at a certain time, you’ll be fine.

What’s that? You want this to run on the 1st of every month? Bang out of luck, sorry. You want to run it every hour between 9 and 5? I guess you could just create a trigger for each hour. The New-ScheduledTaskTrigger PowerShell command is so limited compared to the GUI that Microsoft has had since Scheduled Tasks began. It does my head in how limited it is.

There is a simple work around, and in fact I think it makes the whole process of setting up a Scheduled Task even easier. Here’s my process:

  • Open Task Scheduler UI and create your scheduled task like normal
  • Export the task to xml by right clicking on the task and choosing export. Side note – you could add this to source control so you have a copy of it and can see the changes in the future
  • Delete the scheduled task so we don’t have a 2nd copy of it
  • Repeat the above steps for each scheduled task you want to create.
  • Create the Clustered Scheduled Task using PowerShell
foreach ($file in Get-ChildItem *.xml) {
    $xmlContents = get-content $file.FullName -Raw
    Register-ClusteredScheduledTask -TaskName $file.BaseName -TaskType AnyNode -Xml $xmlContents
}

Important – Make sure that the Xml parameter is the last one specified in the PowerShell command, otherwise it doesn’t work.

You now have a scheduled task that will run as long as one of the nodes in the cluster is running. You can shutdown, patch, pull the plug on any node, and know that your scheduled tasks will be just fine.

6 Comments

George Walkey

Jul 7, 2020, 2:19 am

Absolutely not!
Half the Time Scheduled Tasks never fire

SQL Server Agent is much more capable and stable

Greg

Jul 7, 2020, 7:04 am

If this was a SQL Server, then I agree about using SQL Agent. In this case it wasn’t for SQL Server.

I’ve had problems with tasks not firing before, there was a known bug when importing jobs from an old to new version of Windows Server. Otherwise it’s been pretty reliable, and adding failover redundancy has made that even more reliable.

Matt

Aug 8, 2020, 1:00 am

Last time I looked into this I was blocked due to clustered tasks not supporting domain “run-as” accounts.

Do you know if that has been addressed?

Greg

Aug 8, 2020, 7:18 am

Great question Matt. There’s no parameter you can pass through in PowerShell, but it might pick it up if you create your task in XML

Toby

Sep 9, 2023, 2:57 pm

Thanks for this – Helped enormously with our randomly complex schedules!

I’ve tried importing them as XML with a domain Principal and got nowhere. A series of errors about invalid parameters, so not optimistic.

Looking at using this with Storage Spaces cluster as a way to run / manage the SQL Server backups. Reliable FileShare combined with a reliable task scheduler that isn’t costing me SQL Server per core prices…

Greg

Sep 9, 2023, 4:39 pm

No worries, but why not use SQL Agent to manage your backups? I’m on board with the destination being on storage spaces, but you don’t need a scheduled task to do that.

Leave a Reply