SQL Server Agent Jobs Not Running After Windows Server Time Change

 

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_date and next_run_time from 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:

  1. Disabling job schedules before the time change
  2. Making the time change
  3. Re-enabling schedules after — so next run times are calculated against the correct clock from the start

Comments