programing

Powershell 서비스가 중지되거나 시작될 때까지 기다립니다.

muds 2023. 10. 23. 22:10
반응형

Powershell 서비스가 중지되거나 시작될 때까지 기다립니다.

저는 이 포럼과 구글을 통해서 모두 검색해 보았는데 필요한 것을 찾을 수가 없습니다.스크립트가 꽤 커서 다음 단계로 진행하기 전에 서비스가 시작되는지 또는 중단되는지 확인할 코드를 찾고 있습니다.

정지 또는 시작될 때까지 순환해야 하는 기능 자체입니다(정지된 기능과 시작된 기능이 있습니다).

이름이 거의 같은 총 4개의 서비스를 제공하므로 * 서비스 버스를 와일드카드로 사용할 수 있습니다.

믹키가 올린 '카운트' 전략이 작동하지 않아 해결 방법은 다음과 같습니다.

searchString(서비스 버스 *일 수 있음)과 서비스가 도달해야 할 상태를 나타내는 함수를 만들었습니다.

function WaitUntilServices($searchString, $status)
{
    # Get all services where DisplayName matches $searchString and loop through each of them.
    foreach($service in (Get-Service -DisplayName $searchString))
    {
        # Wait for the service to reach the $status or a maximum of 30 seconds
        $service.WaitForStatus($status, '00:00:30')
    }
}

이제 함수를 호출할 수 있습니다.

WaitUntilServices "Service Bus *" "Stopped"

아니면

WaitUntilServices "Service Bus *" "Running"

시간 초과 기간에 도달하면 그다지 우아하지 않은 예외가 표시됩니다.

Exception calling "WaitForStatus" with "2" argument(s): "Time out has expired and the operation has not been completed."

mgarde의 답변 외에, 한 번의 서비스를 기다리고 싶은 경우(Shay Levy의 게시물에서 영감을 얻은) 이 한 편의 정기선이 유용할 수 있습니다.

(Get-Service SomeInterestingService).WaitForStatus('Running')

다음은 "Running" 상태의 서비스 수가 0(따라서 서비스가 중지됨)이 될 때까지 지정된 서비스의 상태를 루프하고 확인하므로 서비스가 중지되기를 기다리는 경우 이를 사용할 수 있습니다.

추가했습니다.$MaxRepeat을 영원히 e. 이것은 이것이 영원히 실행되는 것을 방지할 것입니다.정의된 대로 최대 20배 실행됩니다.

$services = "Service Bus *"
$maxRepeat = 20
$status = "Running" # change to Stopped if you want to wait for services to start

do 
{
    $count = (Get-Service $services | ? {$_.status -eq $status}).count
    $maxRepeat--
    sleep -Milliseconds 600
} until ($count -eq 0 -or $maxRepeat -eq 0)

이 서비스는 의도적으로 시작이 느리고 멈추기 때문에 여러 개의 카운터로 조정해야 했습니다.원작 대본이 제 궤도에 올랐습니다.실제로 서비스를 다시 시작하기 때문에 서비스가 완전히 중지된 상태가 될 때까지 기다려야 다음 단계로 넘어갈 수 있었습니다.아마 '잠'을 없앨 수 있겠지만, 그냥 놔두는 건 상관없어요.아마 모든 것을 제거하고 $stopped 변수만 사용할 수 있을 것입니다.:)

    # change to Stopped if you want to wait for services to start
    $running = "Running" 
    $stopPending = "StopPending"
    $stopped = "Stopped"
    do 
    {
        $count1 = (Get-Service $service | ? {$_.status -eq $running}).count
        sleep -Milliseconds 600
        $count2 = (Get-Service $service | ? {$_.status -eq $stopPending}).count
        sleep -Milliseconds 600
        $count3 = (Get-Service $service | ? {$_.status -eq $stopped}).count
        sleep -Milliseconds 600
    } until ($count1 -eq 0 -and $count2 -eq 0 -and $count3 -eq 1)

Azure 빌드/배포 파이프라인에서 서비스를 시작 및 중지할 때 이와 같이 사용합니다(이전에 이미 'Stop' 명령을 비동기적으로 전송한 후). 다음과 같은 모든 전환 상태에서 작동합니다.Starting,Stopping,Pausing그리고.Resuming를 함)라고 .StartPending,StopPending,PausePending그리고.ContinuePending(상태 열거).

# Wait for services to be stopped or stop them
$ServicesToStop | ForEach-Object {
  $MyService = Get-Service -Name $_ -ComputerName $Server;
  while ($MyService.Status.ToString().EndsWith('Pending')) {
    Start-Sleep -Seconds 5;
    $MyService.Refresh();
  };
  $MyService | Stop-Service -WarningAction:SilentlyContinue;
  $MyService.Dispose();
};

원격 서버에서 작동하려면 기존의 파워셸이 필요한데, 이 필요합니다.pwsh.exe매개 변수를 포함하지 않음-ComputerName.

제 생각에 카운터는 필요하지 않습니다. 전환 상태에서만 cmdlet이 실패하고 가까운 미래에 지원되는 상태 중 하나로 변경됩니다(a의 경우 최대 125초).Stop명령).

@Christoph에 대한 답변에 더 자세한 내용을 덧붙이기 위해

여기 서비스를 중지하고 프로세스도 중지되도록 하기 위해 최근에 만든 스크립트가 있습니다.우리의 경우에는 그 과정들이 예측 가능했습니다.동일한 실행 파일에서 여러 서비스를 실행하는 경우 서비스/프로세스 ID 매핑을 얻기 위해 더 많은 작업을 수행해야 할 수도 있습니다.

$MaxWait = 180 #seconds

$ServiceNames = "MyServiceName*"
$ProcName = 'MyServiceProcName' #for the services
    
$sw = [System.Diagnostics.Stopwatch]::StartNew() # to keep track of 
$WaitTS = (New-TimeSpan -Seconds $MaxServiceWait) #could also use a smaller interval if you want more progress updates
    
$InitialServiceState = get-service $ServiceNames | select Name,Status,StartType
    

    
write-Host "$ENV:COMPUTERNAME Stopping $ServiceNames"
    
$sw.Restart()
$Services = @()
$Services += Get-Service $ServiceNames | where Status -EQ Running | Stop-Service -PassThru -NoWait #nowait requires powershell 5+
$Services += Get-Service $ServiceNames | where Status -Like *Pending

#make sure the processes are actually stopped!
while (Get-Process | where Name -Match $ProcName)
{
    #if there were services still running
    if ($Services) {
        Write-Host "$ENV:COMPUTERNAME ...waiting up to $MaxServiceWait sec for $($Services.Name)"
        #wait for the service to stop
        $Services.WaitForStatus("Stopped",$WaitTS)
         
    }
    #if we've hit our maximum wait time
    if ($sw.Elapsed.TotalSeconds -gt $MaxServiceWait) {
        Write-Host "$ENV:COMPUTERNAME Waited long enough, killing processes!"
        Get-Process | where name -Match $ProcName | Stop-Process -Force
    }
    Start-Sleep -Seconds 1

    #get current service state and try and stop any that may still be running
    #its possible that another process tried to start a service while we were waiting
    $Services = @()
    $Services += Get-Service $ServiceNames | where Status -EQ Running | Stop-Service -PassThru  -NoWait #nowait requires powershell 5+
    $Services += Get-Service $ServiceNames | where Status -Like *Pending
}

언급URL : https://stackoverflow.com/questions/28186904/powershell-wait-for-service-to-be-stopped-or-started

반응형