The Problem
You've just changed the system time on your Windows Server — whether it's a timezone adjustment, DST correction, or a clock sync after drift. Everything looks fine until you notice your SQL Server Agent jobs are silently not running.
The reason is simple: SQL Server Agent calculates the next run time based on the system clock at the moment the schedule was last evaluated. When you shift the clock forward, all future "next run" times get pushed into the future too. If a job was supposed to run at 02:00 and you moved the clock forward by an hour, SQL Agent thinks it already calculated the next run as 02:00 tomorrow — and just waits.
The result: jobs sit idle, no errors, no alerts. Everything looks healthy in SSMS, but nothing is executing.
Why Simply Restarting SQL Agent Doesn't Always Help
Restarting the SQL Server Agent service forces a recalculation of schedules — and sometimes that's enough. But in enterprise environments with dozens or hundreds of jobs across multiple instances, restarting the agent can be disruptive, and some schedules still don't recalculate correctly depending on the SQL Server version and schedule type.
The reliable fix is to disable and re-enable each job's schedule, which forces SQL Agent to recalculate the next run time from the current clock.
The Fix — PowerShell with dbatools
The cleanest approach is to use dbatools to disable all job schedules and immediately re-enable them. This triggers a fresh next-run-time calculation without touching the jobs themselves.
Step 1 — Disable all job schedules
Get-DbaAgentJob -SqlInstance $source |
Where-Object {
$_.IsEnabled -eq $true -and
$_.Category -notlike "REPL*" -and
$_.Category -notlike "*Shipp*"
} | ForEach-Object {
if ($_.JobSchedules.Count -gt 0) {
foreach ($schedule in $_.JobSchedules) {
if ($schedule.IsEnabled) {
$schedule.IsEnabled = $false
$schedule.Alter()
Write-Host "Disabled schedule '$($schedule.Name)' on job '$($_.Name)'"
}
}
}
}
Step 2 — Re-enable all job schedules
Get-DbaAgentJob -SqlInstance $source |
Where-Object {
$_.IsEnabled -eq $true -and
$_.Category -notlike "REPL*" -and
$_.Category -notlike "*Shipp*"
} | ForEach-Object {
if ($_.JobSchedules.Count -gt 0) {
foreach ($schedule in $_.JobSchedules) {
if (-not $schedule.IsEnabled) {
$schedule.IsEnabled = $true
$schedule.Alter()
Write-Host "Enabled schedule '$($schedule.Name)' on job '$($_.Name)'"
}
}
}
}
Note: Replication (
REPL*) and shipping (*Shipp*) jobs are excluded intentionally — these have their own scheduling mechanisms and should not be touched.
Key Points
- This affects all SQL Server versions when the Windows system clock is changed manually
- The issue is silent — no errors are logged, jobs simply don't fire
- The fix works by forcing SQL Agent to recalculate
next_run_dateandnext_run_timefrom scratch - Always verify after the fix by checking Job Activity Monitor in SSMS and confirming next run times look correct
Prevention
If you need to change the system time on a SQL Server host, consider:
- Disabling job schedules before the time change
- Making the time change
- Re-enabling schedules after — so next run times are calculated against the correct clock from the start
Comments
Post a Comment