Clustered Scheduled Tasks tied to a Resource

By Greg 6 comments

In a previous post, we saw how you can create a task to run on any available node in a Windows Cluster. That’s great when all of the nodes in the cluster can do the job, but what if you need the task to run on a particular node? Or more importantly, what happens if you need the scheduled task to happen on the node currently hosting a particular process. Maybe it’s a scheduled task that has to fire off a process to run. Maybe the executable you want to run is only deployed on certain nodes that can host a particular role. Whatever the reason, it turns out that you can do that fairly easily with the Task Type Resource Specific.

If you want to do something similar, take our original script, and change -TaskType to ResouceSpecific and -Resource to be the name of the clustered service you want to link it to. The PowerShell to run is basically the same as last time:

foreach ($file in Get-ChildItem *.xml) {
    $xmlContents = get-content $file.FullName -Raw
    Register-ClusteredScheduledTask -TaskName $file.BaseName -TaskType ResourceSpecific -Resource MyResouce -Xml $xmlContents
}

If you already have your tasks registered, then you’ll need to re-register them. I haven’t been able to find a way to change from AnyNode to ResourceSpecific. If you have all of the tasks exported as XML, you could adapt the script with something like the below:

foreach ($file in Get-ChildItem *.xml) {
    $xmlContents = Export-ScheduledTask -TaskName $file.BaseName -TaskPath "\Microsoft\Windows\Failover Clustering"
    Unregister-ClusteredScheduledTask -TaskName $file.BaseName
    Register-ClusteredScheduledTask -TaskName $file.BaseName -TaskType ResourceSpecific -Resource MyResouce -Xml $xmlContents
}

The other option for TaskType is ClusterWide. Cluster Wide means all nodes in the cluster will run the scheduled task on the same trigger, i.e. you’ll have multiple copies running at the same time. This could be useful for some sort of cleanup task or logging task, where each node needs to clean up after itself or move all of the logs to a central location at a particular time.

6 Comments

Yael

Apr 4, 2022, 2:25 am

What resource to you select when you want to run the task on the node that has the D drive for example?
I’m not finding any information only

Greg

Apr 4, 2022, 8:19 am

I’ve always put in the name of the “Role” that I want it bound to. So if you have a D drive that fails over between nodes, then bind it to the Role that does that failover.

Scott

Aug 8, 2023, 8:15 am

How do I query what Resource a ClusteredScheduledTask was registered with?

$task = Get-ClusteredScheduledTask -TaskName MyTask

$task.??? to tell me the -Resource that it was registered with?

Greg

Aug 8, 2023, 1:17 pm

You can. I don’t have a script for it, but $task.Resource will give you a guid. If you do Get-ClusterResource -Cluster [cluster name] that’ll give you a list of resources. Each item in that list has a .Id that is a guid. If you match those up, you’ll get the resource.

Scott

Aug 8, 2023, 8:16 am

Yeah, I eventually got there, but since I’m a PS novice I’ve never programmatically (in PS) looped across the result of “Get-ClusterResource” to automate the finding of the Resource.

Got a suggestion on a good Quick-Start on looping collections to match of property?

Greg

Aug 8, 2023, 7:29 am

You’d need a powershell for-each to loop through. You can just do this with a Where-Object though. Assuming $x is your scheduled task object, you can say:
Get-ClusterResource -Cluster ClusterName | Where-Object {$_.Id -eq $x.Resource}

Leave a Reply