Programing

원격 Windows 서비스 중지 / 시작 및 열기 / 닫기 대기

lottogame 2020. 11. 14. 09:42
반응형

원격 Windows 서비스 중지 / 시작 및 열기 / 닫기 대기


이 질문에 대한 상위 답변 은 원격 서비스를 중지 / 시작하는 방법을 알려줍니다. 큰. 이제 필요한 것은 실제 중지 / 시작이 완료 될 때까지 기다리는 것입니다. 그래서 내가 찾고있는 것은 다음과 같은 dos 명령입니다.

  1. 서비스 시작, 서비스가 시작된 후에 만 ​​반환되어야 함 (또는 시간 초과 후 오류 수준 상승)
  2. 서비스를 중지하고 서비스가 중지 된 후에 만 ​​반환

이를 위해 sc.exe를 사용하는 배치 스크립트 세트를 만들었습니다. 아래에 첨부되어 있습니다. 이러한 스크립트를 실행하려면 대상 컴퓨터에 대한 관리 권한이 있고 동일한 도메인의 구성원 인 컴퓨터에서이를 실행하는 사용자 여야합니다 . 도메인 외부 (예 : VPN)에서 실행할 수 있도록 설정할 수 있지만 방화벽, DCOM 및 보안 자격 증명을 통해 작동 할 수있는 많은 보안 계층이 있습니다.

언젠가는 훨씬 더 쉬운 PowerShell에 해당하는 것을 알아낼 것입니다.

safeServiceStart.bat

@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

safeServiceStop.bat

@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

safeServiceRestart.bat

@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 또는 서비스 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 <server> <timeout>\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 /t 2 /nobreak >NUL

다음과 함께 :

ping -n 2 127.0.0.1  1>NUL

2011 년 10 월 20 일 편집-내 코드를 업데이트했습니다. 완전히 디버깅하기 전에 게시했습니다. Eric Falsken에게 감사드립니다. 정말 훌륭한 솔루션입니다. 나는 Eric의 코드를 수정했습니다. 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.

PowerShell 및 Restart-Service 커맨드 렛은 어떻습니까? :)

Get-Service W3SVC -computer myserver | Restart-Service

Eric Falsken의 스크립트는 이러한 목적에 환상적입니다. 그러나 Vista / Server2003 이상에서만 사용할 수있는 timeout 명령을 사용합니다. XP 시스템의 경우 대신 NT Resource Kit의 sleep.exe를 사용할 수 있습니다. (이것은 Eric의 대답에 대한 칭찬이어야하지만 그렇게하기에는 충분하지 않습니다.)


Eric Falsken의 대본을 개선하고 Gerorge Perkins가 수정했습니다.

변경 사항 :

  • 이제는 재시작 스크립트가 아닙니다. 스크립트는 로컬 또는 원격 서비스를 시작, 중지 및 다시 시작할 수 있습니다.
  • 제거 된 로깅 (원하는 경우 SCRIPT_NAME.bat> logfile.txt를 실행하여 간단히 사용할 수 있음)
  • 희소 최적화.

    @ECHO 끄기
    ::이 스크립트는 원래 Eric Falsken이 작성했습니다. http://stackoverflow.com/
    :: 조지 퍼킨스 수정 2011 년 10 월 20 일
    :: Armando Contestabile 수정 2015 년 2 월 23 일
    "% 1"== ""인 경우 사용법으로 이동
    "% 2"== ""인 경우 사용법으로 이동
    
    작업 설정 = % 1
    SET SERVICENAME = % 2
    
    "% 3"== ""인 경우 (
        시스템 이름 = % COMPUTERNAME % 설정
    ) ELSE (
        시스템 이름 설정 = % 3
    )
    
    IF "% ACTION %"== "중지"(
        SET ACTION = STOP
    ) ELSE IF "% ACTION %"== "STOP"(
        SET ACTION = STOP
    ) ELSE IF "% ACTION %"== "시작"(
        SET ACTION = 시작
    ) ELSE IF "% ACTION %"== "시작"(
        SET ACTION = 시작
    ) ELSE IF "% ACTION %"== "다시 시작"(
        SET ACTION = 다시 시작
    ) ELSE IF "% ACTION %"== "다시 시작"(
        SET ACTION = 다시 시작
    ) ELSE GOTO 사용법
    
    설정 상태 =
    SET CURRENT_STATUS =
    SET / A DEFAULT_DELAY = 5
    SET / A SLEEP_COUNT = 0
    SET / A RESTARTED = 0
    SET / A MAX_WAIT_PERIODS = 5
    
    에코.
    ECHO % SYSTEMNAME % 컴퓨터에서 % SERVICENAME % 서비스를 % ACTION %하려고합니다.
    
    PING -n 1 % SYSTEMNAME % | "TTL ="> nul 2> & 1 찾기
    ERRORLEVEL 1 인 경우 ERRORLEVEL 2가 아닌 경우
        에코 실패! 서버 \\ % SYSTEMNAME % 또는 서비스 % SERVICENAME %에 액세스 할 수 없거나 오프라인 상태입니다!
        종료 / B 1
    )
    SC \\ % SYSTEMNAME % 쿼리 % SERVICENAME % | "FAILED 1060"> nul 2> & 1 찾기
    ERRORLEVEL 0 인 경우 ERRORLEVEL 1 (
        에코 실패! % SERVICENAME % 서비스가 유효하지 않습니다!
        종료 / B 2
    )
    SC \\ % SYSTEMNAME % 쿼리 % SERVICENAME % | "상태"찾기> nul 2> & 1
    ERRORLEVEL 1 인 경우 ERRORLEVEL 2가 아닌 경우
        에코 실패! 서버 \\ % SYSTEMNAME % 또는 서비스 % SERVICENAME %에 액세스 할 수 없거나 오프라인 상태입니다!
        종료 / B 3
    )
    
    :급파
    FOR / f "tokens = *"%% i IN ( 'SC \\ % SYSTEMNAME % query % SERVICENAME % ^ | FIND "STATE"') DO SET STATE = %% i
    
    에코 % STATE % | FINDSTR / C : "1"> nul
    % ERRORLEVEL % == 0 인 경우 SET CURRENT_STATUS = STOPPED
    에코 % STATE % | FINDSTR / C : "2"> nul
    % ERRORLEVEL % == 0 인 경우 SET CURRENT_STATUS = START_PENDING
    에코 % STATE % | FINDSTR / C : "3"> nul
    % ERRORLEVEL % == 0 인 경우 SET CURRENT_STATUS = STOP_PENDING
    에코 % STATE % | FINDSTR / C : "4"> nul
    % ERRORLEVEL % == 0 인 경우 SET CURRENT_STATUS = RUNNING
    에코 % STATE % | FINDSTR / C : "5"> nul
    % ERRORLEVEL % == 0 인 경우 SET CURRENT_STATUS = CONTINUE_PENDING
    에코 % STATE % | FINDSTR / C : "6"> nul
    % ERRORLEVEL % == 0 인 경우 SET CURRENT_STATUS = PAUSE_PENDING
    에코 % STATE % | FINDSTR / C : "7"> nul
    % ERRORLEVEL % == 0 인 경우 SET CURRENT_STATUS = PAUSED
    
    ECHO 현재 서비스 상태는 % CURRENT_STATUS %입니다.
    
    "% CURRENT_STATUS %"== "실행 중"이 아니면 "% CURRENT_STATUS %"== "중지"가 아니면 "% CURRENT_STATUS %"== "PAUSED"(
        IF "% SLEEP_COUNT %"== "% MAX_WAIT_PERIODS %"(
            ECHO 서비스 상태는 변경되지 않습니다. 스크립트 실행이 취소됩니다.
            종료 / B 4
        )
        ECHO 서비스 상태가 변경 중입니다. % DEFAULT_DELAY % 초 대기 중 ...
        수면 % DEFAULT_DELAY %
        SET / A SLEEP_COUNT + = 1
        GOTO 파견
    )
    
    IF "% ACTION %"== "시작"(
        IF "% CURRENT_STATUS %"== "실행 중"(
            ECHO 서비스 % SERVICENAME %이 실행 중입니다.
            GOTO EndExit
        ) ELSE (
            GOTO StartService
        )
    ) ELSE IF "% ACTION %"== "다시 시작"(
        IF "% CURRENT_STATUS %"== "실행 중"(
            % RESTARTED % == 1 인 경우 (
                ECHO 서비스 % SERVICENAME %이 다시 시작되었습니다.
                GOTO EndExit
            )
            SET / A SLEEP_COUNT = 0
            GOTO StopService
        ) ELSE (
            SET / A RESTARTED = 1
            GOTO StartService
        )
    ) ELSE IF "% ACTION %"== "중지"(
        IF "% CURRENT_STATUS %"== "중지"(
            ECHO 서비스 % SERVICENAME %이 중지되었습니다.
            GOTO EndExit
        ) ELSE (
            GOTO StopService
        )
    )
    
    : StartService
    ECHO \\ % SYSTEMNAME %에서 % SERVICENAME % 시작
    SC \\ % SYSTEMNAME % start % SERVICENAME %> nul 2> & 1
    SET SLEEP_COUNT = 0
    GOTO 파견
    
    : StopService
    \\ % SYSTEMNAME %에서 % SERVICENAME %을 (를) 중지하는 에코
    SC \\ % SYSTEMNAME % 중지 % SERVICENAME %> nul 2> & 1
    SET SLEEP_COUNT = 0
    GOTO 파견
    
    :용법
    ECHO이 스크립트는 ^ (필요한 경우 ^) 서비스가 중지 / 시작될 때까지 기다리면서 로컬 또는 원격 서비스를 시작 / 중지 / 다시 시작할 수 있습니다.
    에코.
    에코 사용법 :
    에코 % 0 ^ <시작 ^ | 중지 ^ | 다시 시작 ^> ^ <서비스 ^> [시스템]
    에코.
    ECHO SYSTEM이 제공되지 않으면 스크립트는 로컬 시스템에서 실행을 시도합니다.
    종료 / B 5
    
    : EndExit
    에코.
    종료 / B 0
    

NET START 및 NET STOP은 서비스가 서비스가 성공적으로 시작 또는 중지되었음을 나타낼 때까지 반환되지 않아야합니다.


I don't believe you can do this with a straight dos command. You might check Code Project or other similar sites to see if there's a custom solution for this already.

If not, you could write a secondary Windows service that does this for you by exposing the start/stop functionality through a WCF endpoint. To access this secondary service remotely, you could write a simple console app that connects to this service to start/stop the Windows service in question. Since it's a console app, it would mimic the desired behavior of working from the command line and not returning until complete (or an error occurred). It's not the straightforward, simple solution you're looking for, but I'll throw it out there for consideration.

참고URL : https://stackoverflow.com/questions/1405372/stopping-starting-a-remote-windows-service-and-waiting-for-it-to-open-close

반응형