2012-09-21 6 views
8

Używamy cmdletu stop-service do zabicia kilku usług na naszych skrzynkach. W większości przypadków działa świetnie, ale mamy jedną lub dwie usługi (kto nie?), Które czasami nie grają ładnie.Limit czasu polecenia cmdlet stop-service jest możliwy?

W tym przypadku jeden z omawianych usług pozostanie w stanie zatrzymania, a cmdlet kładzie na to do konsoli w kółko:

[08:49:21]WARNING: Waiting for service 'MisbehavingService (MisbehavingService)' to finish 
[08:49:21]stopping... 
[08:49:23]WARNING: Waiting for service 'MisbehavingService (MisbehavingService)' to finish 
[08:49:23]stopping... 
[08:49:25]WARNING: Waiting for service 'MisbehavingService (MisbehavingService)' to finish 
[08:49:25]stopping... 

Ostatecznie musimy zabić usługę w zadaniu menedżer, a nasz skrypt kontynuuje.

Czy istnieje sposób na odrzucenie polecenia cmdlet usługi stop lub przekroczenie limitu czasu po określonym punkcie? Sądzę, że możemy sprawdzić później, a jeśli usługa jest nadal uruchomiona, użyj polecenia cmdlet kill-process, aby zapewnić końcowy fragment.

Odpowiedz

3

Nie ma opcji limitu czasu dla usługi stop, ale jeśli istnieją usługi zależne, konieczne może być użycie opcji -force.

Usługi mogą definiować wskazówkę dotyczącą oczekiwania (która określa limit czasu) po uruchomieniu, ale limit czasu jest kontrolowany przez usługę. Wszelkie żądania sterowania usługami (uruchamianie, zatrzymywanie, wstrzymywanie, wznawianie) przechodzą przez menedżera sterowania usługą (SCM) i będą respektować wskazówkę dotyczącą oczekiwania dla każdej usługi. Jeśli wskazówka dotycząca oczekiwania zostanie przekroczona, operacja zakończy się niepowodzeniem i zostanie zwrócony błąd.

Można użyć polecenia invoke, aby uruchomić usługę Stop-Service jako zadanie i sprawdzać ją okresowo. Jeśli nie zakończyło się, możesz użyć Stop-Process, aby zabić proces i kontynuować.

+0

Dzięki Steven. Myślę, że ta dyskusja poniżej zawiera także kilka dobrych rad dotyczących tego tematu. W szczególności, ostatni post na stronie: http://www.powershellcommunity.org/Forums/tabid/54/aft/5243/Default.aspx – larryq

+0

To też dobre rzeczy. –

7

Chociaż Stop-Service nie ma parametr czasu oczekiwania, sposób WaitForStatus od klasy System.ServiceController ma przeciążenia, która przyjmuje parametr czasu oczekiwania (opisane here). Na szczęście jest to dokładnie ten typ obiektu, który zwraca komenda Get-Service.

Oto prosta funkcja, która pobiera nazwę usługi i limit czasu w sekundach. Zwraca $true, jeśli usługa zostanie zatrzymana przed osiągnięciem limitu czasu, i $false, jeśli upłynie limit czasu połączenia (lub jeśli usługa nie jest dostępna).

function Stop-ServiceWithTimeout ([string] $name, [int] $timeoutSeconds) { 
    $timespan = New-Object -TypeName System.Timespan -ArgumentList 0,0,$timeoutSeconds 
    $svc = Get-Service -Name $name 
    if ($svc -eq $null) { return $false } 
    if ($svc.Status -eq [ServiceProcess.ServiceControllerStatus]::Stopped) { return $true } 
    $svc.Stop() 
    try { 
     $svc.WaitForStatus([ServiceProcess.ServiceControllerStatus]::Stopped, $timespan) 
    } 
    catch [ServiceProcess.TimeoutException] { 
     Write-Verbose "Timeout stopping service $($svc.Name)" 
     return $false 
    } 
    return $true 
}