PowerShell Cron Script
I was looking for a way to schedule jobs and yes windows has a task scheduler built in, however I wanted a bit more flexibility and less complexity.
On the unix platform you can use cron. It is a scheduler that uses a simple format to define the time when the process should start and the process command.
I was going to look at using it when I thought about the parsing that would be needed, I dod not want a system that much that I would write a cron parser. So pulling up search I thought to see if I could find someone who has done this. And what do you know, I found a PowerShell script that would test a cron string and return the time of execution. Bingo!
The cron expression tester can be seen below, this is the link to the gist.
To use this script I wrote a very small wrapper around it using my SimpleSettings module, which I probably should put on github at some point. As I use the amazing Windows Terminal I made a profile entry to start the script directly from the drop down menu. So all I do is open up Terminal and start the cron script. I do this as I do not always want the automation to run, this is part of the flexibility. If I was using Task Scheduler in windows I would have to enable/disable them all the time.
The script I use to wrap the Test-CronExpression script is below. I am sure there may be a nicer way to do it but it works, if it works for purpose there is not point in optimizing it any further, time is to important!
I use https://crontab.guru/ to help check and create any entries I need.
Start-CronScheduler.ps1
#Set-SimpleSetting -Section "crontab" -Name "crontab" -Value @(@{cron = "* * * * *"; command = "Get-Date"})
while($true) {
$crontab = Get-SimpleSetting -Section "crontab" -Name "crontab" -DefaultValue @(@{cron = "* * * * *"; command = "Get-Date"})
foreach ($cronJob in $crontab) {
if(Test-CronExpression.ps1 -Expression $cronJob.cron) {
Invoke-Expression -Command $cronJob.command
}
}
$gap = 0
while($gap -eq 0) {
$now = Get-Date
$nextMinute = ($now).AddMinutes(1).AddSeconds($now.Second*-1)
$gap = ($nextMinute - $now).Seconds
}
Start-Sleep -Seconds $gap
}
Add-CronAction.ps1
[CmdletBinding()]
param (
[String]
$CronPattern,
[String]
$Command
)
$crontab = Get-SimpleSetting -Section "crontab" -Name "crontab" -DefaultValue @(@{cron = "* * * * *"; command = "Get-Date"})
wi "Current Cron entries"
$newCronTab = @()
foreach ($cronJob in $crontab) {
wi "$($cronJob.cron) $($cronJob.command)"
$newCronTab += @{cron = $cronJob.cron; command = $cronJob.command}
}
wi "Adding: $CronPattern $Command"
$newCronTab += @{cron = $CronPattern; command = $Command}
wi "New cron entries"
foreach ($cronJob in $newCronTab) {
wi "$($cronJob.cron) $($cronJob.command)"
}
Set-SimpleSetting -Section "crontab" -Name "crontab" -Value $newCronTab