Recipe 7.14. Script: Robust Service RestartA service can be dependent on other services and have other services dependent on it. This is a nice feature because you can configure that in order for ServiceA to run, ServiceB needs to already be running. However, this makes things more complicated when it comes to stopping and starting services. If you want start ServiceA, you also need to make sure ServiceB is running. When it comes to programmatically restarting services, you could just call the StopService and StartService methods on a service. And since a lot of services don't have any dependencies, this will generally work. But if you happen to try restarting a service that has a dependency, the restart will not be successful. The solution to this is to write a bit of code that can handle restarting services, regardless of dependencies. Here is the code: ' This code restarts a service by first stopping all ' dependent services before stopping the target service. ' Then the target service is started and then all dependent ' services are started. Option Explicit ' ------ SCRIPT CONFIGURATION ------ Dim strComputer : strComputer = "." ' e.g., fs-rtp01 Dim strSvcName : strSvcName = "<ServiceName>" ' e.g., dnscache ' ------ END CONFIGURATION --------- Dim objWMI : set objWMI = GetObject("winmgmts:\\" & strComputer & _ "\root\cimv2") Dim objService: set objService = objWMI.Get("Win32_Service.Name='" & _ strSvcName & "'") WScript.Echo "Restarting " & objService.Name & "..." RecursiveServiceStop objService RecursiveServiceStart objService WScript.Echo "Successfully restarted service" Function RecursiveServiceStop ( objSvc ) Dim colServices : set colServices = objWMI.ExecQuery("Associators of " _ & "{Win32_Service.Name='" & objSvc.Name & "'} Where " _ & "AssocClass=Win32_DependentService Role=Antecedent" ) Dim objS for each objS in colServices RecursiveServiceStop objS next Dim intRC : intRC = objSvc.StopService WScript.Sleep 5000 ' Give the service 5 seconds to stop if intRC > 0 then WScript.Echo " Error stopping service: " & objSvc.Name WScript.Quit else WScript.Echo " Successfully stopped service: " & objSvc.Name end if End Function Function RecursiveServiceStart ( objSvc ) Dim intRC : intRC = objSvc.StartService if intRC > 0 then WScript.Echo " Error starting service: " & objSvc.Name WScript.Quit else WScript.Echo " Successfully started service: " & objSvc.Name end if Dim colServices : set colServices = objWMI.ExecQuery("Associators of " _ & "{Win32_Service.Name='" & objSvc.Name & "'} Where " _ & "AssocClass=Win32_DependentService Role=Antecedent" ) Dim objS for each objS in colServices RecursiveServiceStart objS next End Function In order to restart a service, you have to stop all services that are dependent on that service and then stop the service itself. Then to start the service, you have to start the service followed by all dependent services. And that is exactly what this code does. It makes use of a couple of recursive functions that walk through all of the dependent services. |