这个问题的最佳答案告诉我如何停止/启动远程服务.大.现在,我所需要的只是等待实际停止/开始完成.所以,我正在寻找的是dos命令:
启动服务,应该仅在服务启动后返回(或在超时后,提高错误级别)
停止服务,仅在服务停止后返回
Eric Falsken.. 117
我创建了一组使用sc.exe执行此操作的批处理脚本.它们附在下面.要运行这些脚本,您应该是具有目标计算机管理权限并从同一域的成员计算机运行此脚本的用户.可以将其设置为能够从域外运行(例如从VPN),但是通过涉及防火墙,DCOM和安全凭证可以实现许多安全层.
其中一天,我将弄清楚PowerShell的等价物,这应该更容易.
@echo off :: This script originally authored by Eric Falsken IF [%1]==[] GOTO usage IF [%2]==[] GOTO usage ping -n 1 %1 | FIND "TTL=" >NUL IF errorlevel 1 GOTO SystemOffline SC \\%1 query %2 | FIND "STATE" >NUL IF errorlevel 1 GOTO SystemOffline :ResolveInitialState SC \\%1 query %2 | FIND "STATE" | FIND "STOPPED" >NUL IF errorlevel 0 IF NOT errorlevel 1 GOTO StartService SC \\%1 query %2 | FIND "STATE" | FIND "RUNNING" >NUL IF errorlevel 0 IF NOT errorlevel 1 GOTO StartedService SC \\%1 query %2 | FIND "STATE" | FIND "PAUSED" >NUL IF errorlevel 0 IF NOT errorlevel 1 GOTO SystemOffline echo Service State is changing, waiting for service to resolve its state before making changes sc \\%1 query %2 | Find "STATE" timeout /t 2 /nobreak >NUL GOTO ResolveInitialState :StartService echo Starting %2 on \\%1 sc \\%1 start %2 >NUL GOTO StartingService :StartingServiceDelay echo Waiting for %2 to start timeout /t 2 /nobreak >NUL :StartingService SC \\%1 query %2 | FIND "STATE" | FIND "RUNNING" >NUL IF errorlevel 1 GOTO StartingServiceDelay :StartedService echo %2 on \\%1 is started GOTO:eof :SystemOffline echo Server \\%1 is not accessible or is offline GOTO:eof :usage echo %0 [system name] [service name] echo Example: %0 server1 MyService echo. GOTO:eof
@echo off :: This script originally authored by Eric Falsken IF [%1]==[] GOTO usage IF [%2]==[] GOTO usage ping -n 1 %1 | FIND "TTL=" >NUL IF errorlevel 1 GOTO SystemOffline SC \\%1 query %2 | FIND "STATE" >NUL IF errorlevel 1 GOTO SystemOffline :ResolveInitialState SC \\%1 query %2 | FIND "STATE" | FIND "RUNNING" >NUL IF errorlevel 0 IF NOT errorlevel 1 GOTO StopService SC \\%1 query %2 | FIND "STATE" | FIND "STOPPED" >NUL IF errorlevel 0 IF NOT errorlevel 1 GOTO StopedService SC \\%1 query %2 | FIND "STATE" | FIND "PAUSED" >NUL IF errorlevel 0 IF NOT errorlevel 1 GOTO SystemOffline echo Service State is changing, waiting for service to resolve its state before making changes sc \\%1 query %2 | Find "STATE" timeout /t 2 /nobreak >NUL GOTO ResolveInitialState :StopService echo Stopping %2 on \\%1 sc \\%1 stop %2 %3 >NUL GOTO StopingService :StopingServiceDelay echo Waiting for %2 to stop timeout /t 2 /nobreak >NUL :StopingService SC \\%1 query %2 | FIND "STATE" | FIND "STOPPED" >NUL IF errorlevel 1 GOTO StopingServiceDelay :StopedService echo %2 on \\%1 is stopped GOTO:eof :SystemOffline echo Server \\%1 or service %2 is not accessible or is offline GOTO:eof :usage echo Will cause a remote service to STOP (if not already stopped). echo This script will waiting for the service to enter the stopped state if necessary. echo. echo %0 [system name] [service name] {reason} echo Example: %0 server1 MyService echo. echo For reason codes, run "sc stop" GOTO:eof
@echo off :: This script originally authored by Eric Falsken if [%1]==[] GOTO usage if [%2]==[] GOTO usage ping -n 1 %1 | FIND "TTL=" >NUL IF errorlevel 1 GOTO SystemOffline SC \\%1 query %2 | FIND "STATE" >NUL IF errorlevel 1 GOTO SystemOffline :ResolveInitialState SC \\%1 query %2 | FIND "STATE" | FIND "RUNNING" >NUL IF errorlevel 0 IF NOT errorlevel 1 GOTO StopService SC \\%1 query %2 | FIND "STATE" | FIND "STOPPED" >NUL IF errorlevel 0 IF NOT errorlevel 1 GOTO StartService SC \\%1 query %2 | FIND "STATE" | FIND "PAUSED" >NUL IF errorlevel 0 IF NOT errorlevel 1 GOTO SystemOffline echo Service State is changing, waiting for service to resolve its state before making changes sc \\%1 query %2 | Find "STATE" timeout /t 2 /nobreak >NUL GOTO ResolveInitialState :StopService echo Stopping %2 on \\%1 sc \\%1 stop %2 %3 >NUL GOTO StopingService :StopingServiceDelay echo Waiting for %2 to stop timeout /t 2 /nobreak >NUL :StopingService SC \\%1 query %2 | FIND "STATE" | FIND "STOPPED" >NUL IF errorlevel 1 GOTO StopingServiceDelay :StopedService echo %2 on \\%1 is stopped GOTO StartService :StartService echo Starting %2 on \\%1 sc \\%1 start %2 >NUL GOTO StartingService :StartingServiceDelay echo Waiting for %2 to start timeout /t 2 /nobreak >NUL :StartingService SC \\%1 query %2 | FIND "STATE" | FIND "RUNNING" >NUL IF errorlevel 1 GOTO StartingServiceDelay :StartedService echo %2 on \\%1 is started GOTO:eof :SystemOffline echo Server \\%1 or service %2 is not accessible or is offline GOTO:eof :usage echo Will restart a remote service, waiting for the service to stop/start (if necessary) echo. echo %0 [system name] [service name] {reason} echo Example: %0 server1 MyService echo. echo For reason codes, run "sc stop" GOTO:eof
另请注意,检查服务器可用性的ping命令假定服务器位于IPv4上.包括'-4'开关以强制ping使用IPv4可能会更好. (3认同)
andreister.. 10
那么powershell和WaitForStatus呢?例如,下面的脚本将在远程计算机上重新启动SQL Server:
$computer = "COMPUTER_NAME" $me = new-object -typename System.Management.Automation.PSCredential -argumentlist "DOMAIN\user", (convertto-securestring "password" -asplaintext -force) $restartSqlServer = { $sqlServer = get-service mssqlserver $waitInterval = new-timespan -seconds 5 if (-not ($sqlServer.Status -eq "Stopped")) { $sqlServer.Stop() $sqlServer.WaitForStatus('Stopped', $waitInterval) } $sqlServer.Start() $sqlServer.WaitForStatus('Running', $waitInterval) } icm -ComputerName $computer -ScriptBlock $restartSqlServer -Credential $me
Stephen Mart.. 8
我从来没有真正看到过这样做的具体内容,但是在C\C#\ VB或任何其他可以轻松访问Service API的语言中敲出这样的实用程序会非常容易.这是C#中的一些示例.
using System; using System.ComponentModel; using System.ServiceProcess; namespace SCSync { class Program { private const int ERROR_SUCCESS = 0; private const int ERROR_INVALID_COMMAND_LINE = 1; private const int ERROR_NO_ACCESS = 2; private const int ERROR_COMMAND_TIMEOUT = 3; private const int ERROR_NO_SERVICE = 4; private const int ERROR_NO_SERVER = 5; private const int ERROR_INVALID_STATE = 6; private const int ERROR_UNSPECIFIED = 7; static int Main(string[] args) { if (args.Length < 2 || args.Length > 4) { ShowUsage(); return ERROR_INVALID_COMMAND_LINE; } string serviceName = args[0]; string command = args[1].ToUpper(); string serverName = "."; string timeoutString = "30"; int timeout; if (args.Length > 2) { if (args[2].StartsWith(@"\\")) { serverName = args[2].Substring(2); if (args.Length > 3) { timeoutString = args[3]; } } else { timeoutString = args[2]; } } if (!int.TryParse(timeoutString, out timeout)) { Console.WriteLine("Invalid timeout value.\n"); ShowUsage(); return ERROR_INVALID_COMMAND_LINE; } try { ServiceController sc = new ServiceController(serviceName, serverName); switch (command) { case "START": sc.Start(); sc.WaitForStatus(ServiceControllerStatus.Running, new TimeSpan(0, 0, 0, timeout)); break; case "STOP": sc.Stop(); sc.WaitForStatus(ServiceControllerStatus.Stopped, new TimeSpan(0, 0, 0, timeout)); break; case "PAUSE": sc.Pause(); sc.WaitForStatus(ServiceControllerStatus.Paused, new TimeSpan(0, 0, 0, timeout)); break; case "CONTINUE": sc.Continue(); sc.WaitForStatus(ServiceControllerStatus.Running, new TimeSpan(0, 0, 0, timeout)); break; default: Console.WriteLine("Invalid command value.\n"); ShowUsage(); return ERROR_INVALID_COMMAND_LINE; } } catch (System.ServiceProcess.TimeoutException) { Console.WriteLine("Operation timed out.\n"); return ERROR_COMMAND_TIMEOUT; } catch (UnauthorizedAccessException) { Console.WriteLine("You are not authorized to perform this action.\n"); return ERROR_NO_ACCESS; } catch (InvalidOperationException opEx) { Win32Exception winEx = opEx.InnerException as Win32Exception; if (winEx != null) { switch (winEx.NativeErrorCode) { case 5: //ERROR_ACCESS_DENIED Console.WriteLine("You are not authorized to perform this action.\n"); return ERROR_NO_ACCESS; case 1722: //RPC_S_SERVER_UNAVAILABLE Console.WriteLine("The server is unavailable or does not exist.\n"); return ERROR_NO_SERVER; case 1060: //ERROR_SERVICE_DOES_NOT_EXIST Console.WriteLine("The service does not exist.\n"); return ERROR_NO_SERVICE; case 1056: //ERROR_SERVICE_ALREADY_RUNNING Console.WriteLine("The service is already running.\n"); return ERROR_INVALID_STATE; case 1062: //ERROR_SERVICE_NOT_ACTIVE Console.WriteLine("The service is not running.\n"); return ERROR_INVALID_STATE; default: break; } } Console.WriteLine(opEx.ToString()); return ERROR_UNSPECIFIED; } catch (Exception ex) { Console.WriteLine(ex.ToString()); return ERROR_UNSPECIFIED; } return ERROR_SUCCESS; } private static void ShowUsage() { Console.WriteLine("SCSync usage:\n"); Console.WriteLine("SCSync.exe service command\n"); Console.WriteLine(" service The name of the service upon which the command will act. (Required)"); Console.WriteLine(" command The command to execute - one of: start|stop|pause|continue. (Required)"); Console.WriteLine(" server The name of the server on which the target service runs. This must start with \\. (Optional)"); Console.WriteLine(" timeout The timeout period in seconds in which the command should finish. The default is 30 seconds. (Optional)"); Console.WriteLine("\n"); } } }
WaitForStatus只是一个轮询循环,可以用任何其他语言轻松替换.其余的只是OpenService和ControlService.
我创建了一组使用sc.exe执行此操作的批处理脚本.它们附在下面.要运行这些脚本,您应该是具有目标计算机管理权限并从同一域的成员计算机运行此脚本的用户.可以将其设置为能够从域外运行(例如从VPN),但是通过涉及防火墙,DCOM和安全凭证可以实现许多安全层.
其中一天,我将弄清楚PowerShell的等价物,这应该更容易.
@echo off :: This script originally authored by Eric Falsken IF [%1]==[] GOTO usage IF [%2]==[] GOTO usage ping -n 1 %1 | FIND "TTL=" >NUL IF errorlevel 1 GOTO SystemOffline SC \\%1 query %2 | FIND "STATE" >NUL IF errorlevel 1 GOTO SystemOffline :ResolveInitialState SC \\%1 query %2 | FIND "STATE" | FIND "STOPPED" >NUL IF errorlevel 0 IF NOT errorlevel 1 GOTO StartService SC \\%1 query %2 | FIND "STATE" | FIND "RUNNING" >NUL IF errorlevel 0 IF NOT errorlevel 1 GOTO StartedService SC \\%1 query %2 | FIND "STATE" | FIND "PAUSED" >NUL IF errorlevel 0 IF NOT errorlevel 1 GOTO SystemOffline echo Service State is changing, waiting for service to resolve its state before making changes sc \\%1 query %2 | Find "STATE" timeout /t 2 /nobreak >NUL GOTO ResolveInitialState :StartService echo Starting %2 on \\%1 sc \\%1 start %2 >NUL GOTO StartingService :StartingServiceDelay echo Waiting for %2 to start timeout /t 2 /nobreak >NUL :StartingService SC \\%1 query %2 | FIND "STATE" | FIND "RUNNING" >NUL IF errorlevel 1 GOTO StartingServiceDelay :StartedService echo %2 on \\%1 is started GOTO:eof :SystemOffline echo Server \\%1 is not accessible or is offline GOTO:eof :usage echo %0 [system name] [service name] echo Example: %0 server1 MyService echo. GOTO:eof
@echo off :: This script originally authored by Eric Falsken IF [%1]==[] GOTO usage IF [%2]==[] GOTO usage ping -n 1 %1 | FIND "TTL=" >NUL IF errorlevel 1 GOTO SystemOffline SC \\%1 query %2 | FIND "STATE" >NUL IF errorlevel 1 GOTO SystemOffline :ResolveInitialState SC \\%1 query %2 | FIND "STATE" | FIND "RUNNING" >NUL IF errorlevel 0 IF NOT errorlevel 1 GOTO StopService SC \\%1 query %2 | FIND "STATE" | FIND "STOPPED" >NUL IF errorlevel 0 IF NOT errorlevel 1 GOTO StopedService SC \\%1 query %2 | FIND "STATE" | FIND "PAUSED" >NUL IF errorlevel 0 IF NOT errorlevel 1 GOTO SystemOffline echo Service State is changing, waiting for service to resolve its state before making changes sc \\%1 query %2 | Find "STATE" timeout /t 2 /nobreak >NUL GOTO ResolveInitialState :StopService echo Stopping %2 on \\%1 sc \\%1 stop %2 %3 >NUL GOTO StopingService :StopingServiceDelay echo Waiting for %2 to stop timeout /t 2 /nobreak >NUL :StopingService SC \\%1 query %2 | FIND "STATE" | FIND "STOPPED" >NUL IF errorlevel 1 GOTO StopingServiceDelay :StopedService echo %2 on \\%1 is stopped GOTO:eof :SystemOffline echo Server \\%1 or service %2 is not accessible or is offline GOTO:eof :usage echo Will cause a remote service to STOP (if not already stopped). echo This script will waiting for the service to enter the stopped state if necessary. echo. echo %0 [system name] [service name] {reason} echo Example: %0 server1 MyService echo. echo For reason codes, run "sc stop" GOTO:eof
@echo off :: This script originally authored by Eric Falsken if [%1]==[] GOTO usage if [%2]==[] GOTO usage ping -n 1 %1 | FIND "TTL=" >NUL IF errorlevel 1 GOTO SystemOffline SC \\%1 query %2 | FIND "STATE" >NUL IF errorlevel 1 GOTO SystemOffline :ResolveInitialState SC \\%1 query %2 | FIND "STATE" | FIND "RUNNING" >NUL IF errorlevel 0 IF NOT errorlevel 1 GOTO StopService SC \\%1 query %2 | FIND "STATE" | FIND "STOPPED" >NUL IF errorlevel 0 IF NOT errorlevel 1 GOTO StartService SC \\%1 query %2 | FIND "STATE" | FIND "PAUSED" >NUL IF errorlevel 0 IF NOT errorlevel 1 GOTO SystemOffline echo Service State is changing, waiting for service to resolve its state before making changes sc \\%1 query %2 | Find "STATE" timeout /t 2 /nobreak >NUL GOTO ResolveInitialState :StopService echo Stopping %2 on \\%1 sc \\%1 stop %2 %3 >NUL GOTO StopingService :StopingServiceDelay echo Waiting for %2 to stop timeout /t 2 /nobreak >NUL :StopingService SC \\%1 query %2 | FIND "STATE" | FIND "STOPPED" >NUL IF errorlevel 1 GOTO StopingServiceDelay :StopedService echo %2 on \\%1 is stopped GOTO StartService :StartService echo Starting %2 on \\%1 sc \\%1 start %2 >NUL GOTO StartingService :StartingServiceDelay echo Waiting for %2 to start timeout /t 2 /nobreak >NUL :StartingService SC \\%1 query %2 | FIND "STATE" | FIND "RUNNING" >NUL IF errorlevel 1 GOTO StartingServiceDelay :StartedService echo %2 on \\%1 is started GOTO:eof :SystemOffline echo Server \\%1 or service %2 is not accessible or is offline GOTO:eof :usage echo Will restart a remote service, waiting for the service to stop/start (if necessary) echo. echo %0 [system name] [service name] {reason} echo Example: %0 server1 MyService echo. echo For reason codes, run "sc stop" GOTO:eof
那么powershell和WaitForStatus呢?例如,下面的脚本将在远程计算机上重新启动SQL Server:
$computer = "COMPUTER_NAME" $me = new-object -typename System.Management.Automation.PSCredential -argumentlist "DOMAIN\user", (convertto-securestring "password" -asplaintext -force) $restartSqlServer = { $sqlServer = get-service mssqlserver $waitInterval = new-timespan -seconds 5 if (-not ($sqlServer.Status -eq "Stopped")) { $sqlServer.Stop() $sqlServer.WaitForStatus('Stopped', $waitInterval) } $sqlServer.Start() $sqlServer.WaitForStatus('Running', $waitInterval) } icm -ComputerName $computer -ScriptBlock $restartSqlServer -Credential $me
我从来没有真正看到过这样做的具体内容,但是在C\C#\ VB或任何其他可以轻松访问Service API的语言中敲出这样的实用程序会非常容易.这是C#中的一些示例.
using System; using System.ComponentModel; using System.ServiceProcess; namespace SCSync { class Program { private const int ERROR_SUCCESS = 0; private const int ERROR_INVALID_COMMAND_LINE = 1; private const int ERROR_NO_ACCESS = 2; private const int ERROR_COMMAND_TIMEOUT = 3; private const int ERROR_NO_SERVICE = 4; private const int ERROR_NO_SERVER = 5; private const int ERROR_INVALID_STATE = 6; private const int ERROR_UNSPECIFIED = 7; static int Main(string[] args) { if (args.Length < 2 || args.Length > 4) { ShowUsage(); return ERROR_INVALID_COMMAND_LINE; } string serviceName = args[0]; string command = args[1].ToUpper(); string serverName = "."; string timeoutString = "30"; int timeout; if (args.Length > 2) { if (args[2].StartsWith(@"\\")) { serverName = args[2].Substring(2); if (args.Length > 3) { timeoutString = args[3]; } } else { timeoutString = args[2]; } } if (!int.TryParse(timeoutString, out timeout)) { Console.WriteLine("Invalid timeout value.\n"); ShowUsage(); return ERROR_INVALID_COMMAND_LINE; } try { ServiceController sc = new ServiceController(serviceName, serverName); switch (command) { case "START": sc.Start(); sc.WaitForStatus(ServiceControllerStatus.Running, new TimeSpan(0, 0, 0, timeout)); break; case "STOP": sc.Stop(); sc.WaitForStatus(ServiceControllerStatus.Stopped, new TimeSpan(0, 0, 0, timeout)); break; case "PAUSE": sc.Pause(); sc.WaitForStatus(ServiceControllerStatus.Paused, new TimeSpan(0, 0, 0, timeout)); break; case "CONTINUE": sc.Continue(); sc.WaitForStatus(ServiceControllerStatus.Running, new TimeSpan(0, 0, 0, timeout)); break; default: Console.WriteLine("Invalid command value.\n"); ShowUsage(); return ERROR_INVALID_COMMAND_LINE; } } catch (System.ServiceProcess.TimeoutException) { Console.WriteLine("Operation timed out.\n"); return ERROR_COMMAND_TIMEOUT; } catch (UnauthorizedAccessException) { Console.WriteLine("You are not authorized to perform this action.\n"); return ERROR_NO_ACCESS; } catch (InvalidOperationException opEx) { Win32Exception winEx = opEx.InnerException as Win32Exception; if (winEx != null) { switch (winEx.NativeErrorCode) { case 5: //ERROR_ACCESS_DENIED Console.WriteLine("You are not authorized to perform this action.\n"); return ERROR_NO_ACCESS; case 1722: //RPC_S_SERVER_UNAVAILABLE Console.WriteLine("The server is unavailable or does not exist.\n"); return ERROR_NO_SERVER; case 1060: //ERROR_SERVICE_DOES_NOT_EXIST Console.WriteLine("The service does not exist.\n"); return ERROR_NO_SERVICE; case 1056: //ERROR_SERVICE_ALREADY_RUNNING Console.WriteLine("The service is already running.\n"); return ERROR_INVALID_STATE; case 1062: //ERROR_SERVICE_NOT_ACTIVE Console.WriteLine("The service is not running.\n"); return ERROR_INVALID_STATE; default: break; } } Console.WriteLine(opEx.ToString()); return ERROR_UNSPECIFIED; } catch (Exception ex) { Console.WriteLine(ex.ToString()); return ERROR_UNSPECIFIED; } return ERROR_SUCCESS; } private static void ShowUsage() { Console.WriteLine("SCSync usage:\n"); Console.WriteLine("SCSync.exe service command\n"); Console.WriteLine(" service The name of the service upon which the command will act. (Required)"); Console.WriteLine(" command The command to execute - one of: start|stop|pause|continue. (Required)"); Console.WriteLine(" server The name of the server on which the target service runs. This must start with \\. (Optional)"); Console.WriteLine(" timeout The timeout period in seconds in which the command should finish. The default is 30 seconds. (Optional)"); Console.WriteLine("\n"); } } }
WaitForStatus只是一个轮询循环,可以用任何其他语言轻松替换.其余的只是OpenService和ControlService.
Eric Falsken的解决方案非常有效.+1.
但我想补充说,timeout命令有时会失败并出现错误:"不支持输入重定向,立即退出进程"
要解决这个问题,我必须更换timeout命令:
timeout /t 2 /nobreak >NUL
以下内容:
ping -n 2 127.0.0.1 1>NUL
在2011年10月20日编辑 - 更新了我的代码.我在完全调试之前发布了它.非常感谢Eric Falsken.多棒的解决方案.我调整了Eric的代码(如果您打算使用它,BTW会查找几个打字错误).我添加了日志记录和一些额外的错误检查,以了解Eric没有考虑的一些条件.由于我最感兴趣的是服务重启(不只是停止和/或启动),我只建立在Eric的重启代码上.无论如何,我发布我的版本,希望你喜欢它!
@ECHO off :: This script originally authored by Eric Falsken http://stackoverflow.com/ :: Revised for by George Perkins 10/20/2011 IF [%1]==[] GOTO Usage IF [%2]==[] GOTO Usage :SetLocalVariables SET /A MyDelay=0 SET MyHours=%time:~0,2% IF %MyHours%==0 SET MyHours=00 IF %MyHours%==1 SET MyHours=01 IF %MyHours%==2 SET MyHours=02 IF %MyHours%==3 SET MyHours=03 IF %MyHours%==4 SET MyHours=04 IF %MyHours%==5 SET MyHours=05 IF %MyHours%==6 SET MyHours=06 IF %MyHours%==7 SET MyHours=07 IF %MyHours%==8 SET MyHours=08 IF %MyHours%==9 SET MyHours=09 SET MyMinutes=%time:~3,2% SET MySeconds=%time:~6,2% SET MyHundredths=%time:~9,2% SET MyMonth=%date:~4,2% SET MyDay=%date:~-7,2% SET MyCentury=%date:~-4,4% SET MyTimeStamp=%MyCentury%%MyMonth%%MyDay%%MyHours%%MyMinutes%%MySeconds% IF "%3" == "" ( SET MyLog=C:\Temp ) ELSE ( SET MyLog=%3 ) SET MyLogFile=%MyLog%\ServiceRestart%MyTimeStamp%.log ECHO. ECHO. >> %MyLogFile% ECHO ------------- ------------- %MyHours%:%MyMinutes%:%MySeconds%.%MyHundredths% %MyMonth%/%MyDay%/%MyCentury% ------------- ------------- ECHO ------------- ------------- %MyHours%:%MyMinutes%:%MySeconds%.%MyHundredths% %MyMonth%/%MyDay%/%MyCentury% ------------- ------------- >> %MyLogFile% ECHO Begin batch program %0. ECHO Begin batch program %0. >> %MyLogFile% ECHO Logging to file %MyLogFile%. ECHO Logging to file %MyLogFile%. >> %MyLogFile% ECHO Attempting to restart service %2 on computer %1. ECHO Attempting to restart service %2 on computer %1. >> %MyLogFile% PING -n 1 %1 | FIND "TTL=" >> %MyLogFile% IF errorlevel 1 IF NOT errorlevel 2 GOTO SystemOffline SC \\%1 query %2 | FIND "FAILED 1060" >> %MyLogFile% IF errorlevel 0 IF NOT errorlevel 1 GOTO InvalidServiceName SC \\%1 query %2 | FIND "STATE" >> %MyLogFile% IF errorlevel 1 IF NOT errorlevel 2 GOTO SystemOffline :ResolveInitialState SET /A MyDelay+=1 SC \\%1 query %2 | FIND "STATE" | FIND "RUNNING" >> %MyLogFile% IF errorlevel 0 IF NOT errorlevel 1 GOTO StopService SC \\%1 query %2 | FIND "STATE" | FIND "STOPPED" >> %MyLogFile% IF errorlevel 0 IF NOT errorlevel 1 GOTO StartService SC \\%1 query %2 | FIND "STATE" | FIND "PAUSED" >> %MyLogFile% IF errorlevel 0 IF NOT errorlevel 1 GOTO SystemOffline ECHO Service State is changing, waiting %MyDelay% seconds for service to resolve its state before making changes. ECHO Service State is changing, waiting %MyDelay% seconds for service to resolve its state before making changes. >> %MyLogFile% TIMEOUT /t %MyDelay% /nobreak >> %MyLogFile% GOTO ResolveInitialState :StopService SET /A MyDelay=0 ECHO Stopping %2 on \\%1. ECHO Stopping %2 on \\%1. >> %MyLogFile% SC \\%1 stop %2 | FIND "FAILED" >> %MyLogFile% IF errorlevel 0 IF NOT errorlevel 1 GOTO Unstoppable :StoppingServiceDelay SET /A MyDelay+=1 IF %MyDelay%==21 GOTO MaybeUnStoppable ECHO Waiting %MyDelay% seconds for %2 to stop. ECHO Waiting %MyDelay% seconds for %2 to stop. >> %MyLogFile% TIMEOUT /t %MyDelay% /nobreak >> %MyLogFile% :StoppingService SC \\%1 query %2 | FIND "STATE" | FIND "STOPPED" >> %MyLogFile% IF errorlevel 0 IF NOT errorlevel 1 GOTO StoppedService SC \\%1 query %2 | FIND "STATE" | FIND "STOP_PENDING" >> %MyLogFile% IF errorlevel 0 IF NOT errorlevel 1 GOTO StoppingServiceDelay GOTO StoppingServiceDelay :MaybeUnStoppable :: If we got here we waited approximately 3 mintues and the service has not stopped. SC \\%1 query %2 | FIND "NOT_STOPPABLE" >> %MyLogFile% IF errorlevel 0 IF NOT errorlevel 1 GOTO OneLastChance GOTO Unstoppable :OneLastChance SC \\%1 stop %2 >> %MyLogFile% SET /A MyDelay+=1 ECHO Waiting %MyDelay% seconds for %2 to stop. ECHO Waiting %MyDelay% seconds for %2 to stop. >> %MyLogFile% TIMEOUT /t %MyDelay% /nobreak >> %MyLogFile% SC \\%1 query %2 | FIND "STATE" | FIND "STOPPED" >> %MyLogFile% IF errorlevel 0 IF NOT errorlevel 1 GOTO StoppedService SC \\%1 query %2 | FIND "STATE" | FIND "RUNNING" >> %MyLogFile% IF errorlevel 1 IF NOT errorlevel 2 GOTO UnknownState SC \\%1 query %2 | FIND "NOT_STOPPABLE" >> %MyLogFile% IF errorlevel 0 IF NOT errorlevel 1 GOTO Unstoppable GOTO StoppingServiceDelay :StoppedService ECHO %2 on \\%1 is stopped. ECHO %2 on \\%1 is stopped. >> %MyLogFile% GOTO StartService :StartService SET /A MyDelay=0 ECHO Starting %2 on \\%1. ECHO Starting %2 on \\%1. >> %MyLogFile% SC \\%1 start %2 >> %MyLogFile% GOTO StartingService :StartingServiceDelay SET /A MyDelay+=1 ECHO Waiting %MyDelay% seconds for %2 to start. ECHO Waiting %MyDelay% seconds for %2 to start. >> %MyLogFile% TIMEOUT /t %MyDelay% /nobreak >> %MyLogFile% :StartingService SC \\%1 query %2 | FIND "STATE" | FIND "RUNNING" >> %MyLogFile% IF errorlevel 1 IF NOT errorlevel 2 GOTO StartingServiceDelay :StartedService ECHO %2 on \\%1 is started. ECHO %2 on \\%1 is started. >> %MyLogFile% GOTO EndExit :SystemOffline ECHO Failure! Server \\%1 or service %2 is not accessible or is offline! ECHO Failure! Server \\%1 or service %2 is not accessible or is offline! >> %MyLogFile% ECHO See log file %MyLogFile% for details! GOTO EndExit :InvalidServiceName ECHO Failure! Service %2 is not valid! ECHO Failure! Service %2 is not valid! >> %MyLogFile% ECHO See log file %MyLogFile% for details! GOTO EndExit :UnknownState ECHO Failure! Service %2 in an unknown state and cannot be stopped! ECHO Failure! Service %2 in an unknown state and cannot be stopped! >> %MyLogFile% ECHO See log file %MyLogFile% for details! GOTO EndExit :UnStoppable ECHO Failure! Service %2 cannot be stopped! Check dependencies or system state. ECHO Failure! Service %2 cannot be stopped! Check dependencies or system state. >> %MyLogFile% ECHO See log file %MyLogFile% for details! GOTO EndExit :Usage ECHO Will restart a remote service, waiting for the service to stop/start (if necessary). ECHO. ECHO Usage: ECHO %0 [system name] [service name] [logfile path] ECHO Example: %0 server1 MyService C:\Temp\Log ECHO. GOTO EndExit :EndExit ECHO. ECHO %0 Ended. ECHO.