Home / Guides / Windows service recovery vs a watchdog

Restart a Windows service automatically: the Recovery tab vs a watchdog

Windows can restart a failed service for you, for free, with no extra software. It only does so in one situation, though. This guide shows how to set it up, what it never restarts, and what to use for the rest.

Short answer.

Use the built-in Recovery settings for services that crash. They restart a service whose process terminates unexpectedly. They do nothing for a service that was stopped cleanly or by a person, for a service that is running but hung, or for a program that is not a service.

For those cases you need something that checks the service state on a schedule and starts it again: a small PowerShell script run by Task Scheduler, or a dedicated tool such as SvcSentinel.

How the Recovery tab works

Open services.msc, double-click the service, and choose the Recovery tab. You can choose what happens on the first failure, the second failure and every later failure:

  • Restart the Service, after a delay you set in minutes.
  • Run a Program, which runs under the same account as the service. This is how you send yourself an alert.
  • Restart the Computer.
  • Take No Action.

The tab also has Reset fail count after (days). Windows counts failures since the last reset, picks the action for that count, and repeats the last action if the count goes past the end of the list.

To set the same thing from an elevated prompt, which is easier to repeat on many servers, use sc.exe:

sc.exe failure "My Service" reset= 86400 actions= restart/60000/restart/60000/restart/300000

Note the space after each =: sc.exe requires it. Times are in milliseconds, and reset= is in seconds (86400 is one day). sc.exe qfailure "My Service" shows what is currently set.

What the Recovery tab will not restart

Windows treats a service as failed when its process terminates without reporting that it stopped. That is a narrow definition, and these common cases fall outside it:

  • A clean stop. If the service reports that it stopped normally, even by its own decision, nothing is restarted. A stop that ends with an error code only counts if you tick Enable actions for stops with errors on the Recovery tab (sc.exe failureflag "My Service" 1 does the same).
  • A person or a script stopping it. A stop through Services, net stop or a patch installer is a normal stop, not a failure.
  • A hung service. If the process is still alive but has stopped doing its job, the state is still Running, and Windows has nothing to react to.
  • Programs that are not services. Recovery settings exist only for services. A tray app or a console program that dies stays dead.
  • Scheduled restarts. Some services behave better with a regular recycle. That is not part of Recovery; it needs Task Scheduler or a tool.
  • Telling you. Restarting is silent unless you add a Run a Program action that sends a message.

A common surprise: .NET worker services that stop cleanly

If you wrote the service in .NET, note that since .NET 6 an unhandled exception in a BackgroundService stops the host by default, and it stops cleanly, so the Service Control Manager does not see a crash and does not restart it. Microsoft's guidance is to have the service exit with a non-zero exit code (for example by calling Environment.Exit(1) in the catch block) so that the Recovery settings apply. See the Microsoft Learn page linked at the end.

A simple watchdog you can schedule

For everything above, the usual answer is a script that runs every few minutes, looks at the state and starts anything that is stopped. This one takes service names, logs what it did, and supports -WhatIf so you can try it safely:

[CmdletBinding(SupportsShouldProcess)]
param(
    [Parameter(Mandatory)][string[]]$Name,
    [string]$LogFile = "$env:ProgramData\Keep-ServiceRunning.log"
)

foreach ($n in $Name) {
    $svc = Get-Service -Name $n -ErrorAction SilentlyContinue
    if (-not $svc) { Write-Warning "No service named '$n'."; continue }
    if ($svc.Status -ne 'Stopped') { continue }

    if ($PSCmdlet.ShouldProcess($n, 'Start-Service')) {
        try   { Start-Service -InputObject $svc -ErrorAction Stop; $result = 'started' }
        catch { $result = "FAILED: $($_.Exception.Message)" }
        Add-Content -Path $LogFile -Value ('{0:s}  {1}  {2}' -f (Get-Date), $n, $result)
    }
}

Save it as C:\Scripts\Keep-ServiceRunning.ps1, try it with -WhatIf, then schedule it from an elevated prompt:

schtasks /Create /TN "Keep services running" /SC MINUTE /MO 5 /RU SYSTEM /RL HIGHEST /TR "powershell.exe -NoProfile -ExecutionPolicy Bypass -File C:\Scripts\Keep-ServiceRunning.ps1 -Name MyService"

Replace MyService with the service names. The task runs as SYSTEM every five minutes, so a stopped service stays down for about five minutes at most.

What this script does not do: it does not email you, it does not notice a hung service, it does not restart programs that are not services, and it does not pause during maintenance. Adding those is where a script starts to turn into a project.

Questions

Does the Recovery tab restart a service I stopped on purpose?

No. A stop that the service reports normally is not a failure, so no recovery action runs. That is why a patch window or a manual stop does not trigger a restart.

Why did my service not restart after it crashed?

Check that Recovery actions are actually set: a service you install yourself starts with none. Then check how the service exited: a service that stops cleanly, or with an error code while "Enable actions for stops with errors" is off, is not treated as a crash.

Can Windows email me when a service is restarted?

Not by itself. The Recovery tab can run a program on failure, and that program can send a message, but you have to write it. A tool such as SvcSentinel sends the email for you through your own mail server.

How often should a watchdog check?

Often enough that the downtime you can tolerate is covered. A five-minute check means a stopped service is down for five minutes at most. Critical services can be checked more often; a check only reads the service state, so it is cheap.

Does the script restart programs that are not services?

No. It only handles Windows services. Restarting a normal program means launching its executable again, which SvcSentinel's application monitoring does.

Related

Sources (Microsoft Learn): SERVICE_FAILURE_ACTIONS, SERVICE_FAILURE_ACTIONS_FLAG, Create a Windows Service using BackgroundService.

An unhandled error has occurred. Reload 🗙