Skip to content

Monitor a Windows Task Scheduler job

Windows Task Scheduler records a task’s last result, but only someone who opens it on the server sees it. When the script starts failing, the service account’s password expires, or the task is disabled during maintenance, nobody notices. A heartbeat check does: the script reports to Pingstack after it succeeds, and Pingstack alerts you when that report doesn’t arrive on time.

1. Create a heartbeat check that matches the schedule

Section titled “1. Create a heartbeat check that matches the schedule”

Task Scheduler triggers aren’t cron, so translate the trigger:

Task Scheduler trigger Pingstack schedule
Daily at 2:00 AM Cron 0 2 * * *
Weekly on Monday at 6:30 AM Cron 30 6 * * 1
Monthly on day 1 at 3:00 AM Cron 0 3 1 * *
Repeat every 15 minutes Interval of 15 minutes

Create a heartbeat check with the matching schedule. Task Scheduler uses the server’s local time, so choose the server’s timezone in Pingstack. See schedules and timezones.

Set a grace period longer than the task’s usual runtime. Attach a notification group.

2. Store the ping URL where only the task can read it

Section titled “2. Store the ping URL where only the task can read it”

Copy the location’s ping URL from the check in Pingstack. In an elevated PowerShell, save it to a file and restrict it to administrators and the account the task runs as:

Terminal window
$dir = 'C:\ProgramData\Pingstack'
New-Item -ItemType Directory -Force -Path $dir | Out-Null
Read-Host 'Ping URL' | Set-Content -Path "$dir\nightly-export.url" -NoNewline
icacls $dir /inheritance:r /grant:r 'Administrators:F' 'SYSTEM:F' 'DOMAIN\svc-export:R'

Replace DOMAIN\svc-export with the task’s account.

C:\Jobs\nightly-export.ps1
$ErrorActionPreference = 'Stop'
& 'C:\Jobs\export.exe' --target D:\exports
if ($LASTEXITCODE -ne 0) { throw "export.exe exited with $LASTEXITCODE" }
$url = (Get-Content -Raw 'C:\ProgramData\Pingstack\nightly-export.url').Trim()
Invoke-WebRequest -Uri $url -UseBasicParsing -TimeoutSec 10 | Out-Null

$ErrorActionPreference = 'Stop' turns PowerShell errors into failures, and the $LASTEXITCODE check does the same for programs like export.exe, which PowerShell doesn’t stop on by itself. Either way the script stops before the report, and Pingstack alerts you when the deadline passes.

Register the task:

Terminal window
$action = New-ScheduledTaskAction -Execute 'powershell.exe' `
-Argument '-NoProfile -ExecutionPolicy Bypass -File C:\Jobs\nightly-export.ps1'
$trigger = New-ScheduledTaskTrigger -Daily -At 2am
$cred = Get-Credential 'DOMAIN\svc-export'
Register-ScheduledTask -TaskName 'Nightly export' -Action $action -Trigger $trigger `
-User $cred.UserName -Password $cred.GetNetworkCredential().Password

Running as a dedicated account with Run whether user is logged on or not keeps the task independent of who’s signed in.

Start the task by hand:

Terminal window
Start-ScheduledTask -TaskName 'Nightly export'
Get-ScheduledTaskInfo -TaskName 'Nightly export'

When it finishes, open the check in Pingstack and confirm the location received a heartbeat and shows a next deadline.

Append a count the job produces as a numeric value, then set warning and critical thresholds on the check:

Terminal window
$rows = (Get-ChildItem D:\exports -Filter *.csv).Count
Invoke-WebRequest -Uri "$($url)?value=$rows" -UseBasicParsing -TimeoutSec 10 | Out-Null
  • Expired password. A task that stores the account’s password stops starting when the password changes. Update it in the task’s properties, or use a group managed service account.
  • Server asleep or rebooting. Turn on Run task as soon as possible after a scheduled start is missed if late runs are acceptable; the late run reports after Pingstack has already alerted.
  • Time limit. Task Scheduler stops tasks that run longer than the Stop the task if it runs longer than setting.
  • Timezone or daylight saving. Local-time triggers shift with daylight saving. Match the check’s timezone to the server’s.

If alerts still don’t match what you expect, see troubleshooting monitoring.