In an earlier article, I demonstrated how to use PowerShell’s Scheduled Jobs feature. Although I find that this a very useful tool, it is not perfect. One limitation is that you cannot setup a scheduled job to repeat itself.
By that, I mean that you can’t schedule something to run once a week starting at 10:00 AM, where you want the job to repeat every 15 minutes for an hour. If you look at help for New-JobTrigger, you’ll see that you can use repetition.
Unfortunately, this only works if you are creating a one-time job. You can create a daily or weekly job to repeat in the Task Scheduler, so why can’t you use PowerShell? Here’s one way that might work.
If you look at a job trigger object, you’ll see properties for repetition settings.
You might even think you can set these properties and create a new job.
$trigger.RepetitionDuration = (new-timespan -minutes 10 )
$trigger.RepetitionInterval = (new-timespan -Minutes 1)
Register-Scheduledjob -Name 'Weekly Rep Test A' -MaxResultCount 4 -ScriptBlock $a -Trigger $trigger
Sadly, when you look at the job in Task Scheduler, the repetition settings are not configured.
I was hoping that PowerShell would simply apply the trigger object, but that doesn’t seem to be the case. The only time repetition settings appear to be configured is with a one-time job. So how do we solve this? We can use a separate, but related set of cmdlets.
Windows 8 and Windows Server 2012 brought us another module called ScheduledTasks. You can use these cmdlets to manage all scheduled tasks. Because a PowerShell scheduled job is just another scheduled task, we can use the task cmdlets to modify it. Let’s grab the job I just created using Get-ScheduledTask.
$t = get-scheduledtask -TaskName "Weekly Rep Test A"
This object has a triggers property that includes a repetition pattern.
All we need to do is set the Duration and Interval properties. However, the values are not simple timespans. The values are defined using a special string format: P<days>DT<hours>H<minutes>M<seconds>S. For example, an interval of four hours would be PT4H.
For my purposes, I want my test scheduled job to run once a minute for an hour.
$t.Triggers.repetition.Duration = 'PT60M'
$t.Triggers.repetition.Interval = 'PT01M'
That’s all there is to it other than updating the scheduled task.
$t | Set-ScheduledTask
When I refresh the task in Task Scheduler, I now have repetition values.
Because I jumped around a bit, here’s an example from start to finish.
$name = "Daily Rep Test" Register-ScheduledJob -Name $name -Trigger $trigger -ScriptBlock $action -MaxResultCount 4 Start-Sleep -Seconds 5 $task = Get-ScheduledTask -TaskName $Name $task.Triggers.repetition.Duration = 'PT10M'
This is something you can try yourself. You might need to change the path to the text file. The first few lines create a typical PowerShell scheduled job that is simply going to append the date and time to a text file. The job is scheduled to run for five minutes on a daily basis. After the scheduled job is created, I'm pausing a few seconds to give the Task Scheduler time to update. Next, I go back and get the scheduled job with Get-ScheduledTask to update the repetition settings so that my PowerShell command runs every minute for 10 minutes. Interestingly, the scheduled job cmdlets don't recognize these settings. But these settings are present when viewed from task scheduler. This is because the scheduled job definition is stored in an XML file under $env:LocalAppData\Microsoft\Windows\PowerShell\ScheduledJobs. Although you could manually modify the XML, I don't think it would affect the Task Scheduler, which is really the driving force here. I think what I have come up with is the best alternative. Of course, you could simply use the Task Scheduler cmdlets to create a PowerShell related task from the very beginning. You would lose the ability to use scheduled job cmdlets, but that might be okay for your purposes. If you are stuck running Windows 7, it is unlikely that you'll have the ScheduledTasks module, so you'll have to manually configure repetition intervals. I hope you'll let me know if this solves your problem.