One Liners: Setting Recovery Option to ‘restart’ for Lync/Skype4B Services
A client wanted to configure the recovery options for services in Lync to help reduce downtime if/when a service stops. This was no big deal for me, except there are a dozen Lync servers, some of which have quite a few Lync services. I set out to make this easier than manually changing each service’s recovery options.
Service recovery options allow you to define what Windows should do if the service fails. The options are “Take No Action” (the default), “Restart the Service”, “Run a Program”, and “Restart the Computer”. These options can be defined for the first, second, and subsequent service failures. Additional parameters include how long to wait before resetting the failure counter and how long to wait after the service fails before performing the configured failure option. More complex options include running another program:
Unfortunately, PowerShell’s Set-Service doesn’t have a parameter for setting failure options, so we must rely on the command line sc.exe. Sc.exe can be used to create, modify, and delete services. We’ll use this to set our failure options to restart the services. Note: you must use “sc.exe” and not just “sc”, since in PowerShell, “sc” is an alias for Set-Content. The format is
sc.exe [service name] failure reset= [integer] actions= [actions]
Reset is measured in seconds. We’ll use 86400, which is a full 24 hours. Actions are specified as action/wait time in milliseconds. So “restart/5000” means to wait 5000 milliseconds (5 seconds), and then restart the service. The same action will be applied to the first, second, and subsequent service failure.
We’ll use Get-CimInstance with the Win32_Service classname to grab a list of all of the services, piping that to match descriptions that include ‘Lync’ or ‘Skype for Business’, and start modes that are “automatic”. The finished one liner command looks like this:
$services = Get-CimInstance -ClassName 'Win32_Service' | Where-Object {$_.description -imatch 'Lync|Skype for Business' -and $_.StartMode -eq 'Auto'}; foreach ($service in $services){sc.exe failure $service.name reset= 86400 actions= restart/5000}
When we view the properties of the service again, we see that the failure options are set to restart the service, and to reset the counter after 1 day. Since the restart option is only 5 seconds, the “Restart service after” field shows 0 minutes:
You can also specify different actions for each of the failure instances by adding more actions. For instance, let’s say you want to restart the service for the first and second failures, and reboot the server on subsequent failures. Simply combine the actions together, separating them with a slash, such as:
$services = Get-CimInstance -ClassName 'Win32_Service' | Where-Object {$_.description -imatch 'Lync|Skype for Business' -and $_.StartMode -eq 'Auto'}; foreach ($service in $services){sc.exe failure $service.name reset= 86400 actions= restart/5000/restart/5000/reboot/5000}
It might be wise to not set all of the failure instances to taking action, to prevent the server from getting stuck in a loop of taking action when a service is having serious issues. To only set the first two options, just use a double slash for the third, such as:
$services = Get-CimInstance -ClassName 'Win32_Service' | Where-Object {$_.description -imatch 'Lync|Skype for Business' -and $_.StartMode -eq 'Auto'}; foreach ($service in $services){sc.exe failure $service.name reset= 86400 actions= restart/5000/restart/5000//}
Obviously, a good monitoring solution such as System Center Operations Manager (SCOM) should be used to track and alert when services stop, and when other more serious issues arise. You don’t want to get into a scenario where a service is constantly stopping and being restarted without knowing.
Just a note I forgot to mention. The spaces after “reset=” and after “actions=” are critical. Without them, stuff just don’t work.
Thanks for the information. Do you know of a way to get status of recovery options other than using ConverTo-Html? I want to query rather than update.
$SS_Process1 = Get-Service “My Process” | ConvertTo-Html Name,UserName,status,state,StartType,FirstFailure,SecondFailure,ThirdFailure -AS List
Good post! I used the same ps command for other svcs. 🙂