2012-09-21 9 views
8

Stiamo utilizzando il cmdlet di stop-service per eliminare alcuni servizi sulle nostre scatole. Il più delle volte funziona alla grande, tuttavia abbiamo uno o due servizi (chi no?) Che a volte non funzionano bene.timeout del cmdlet di stop-service possibile?

In questo caso uno dei servizi in questione rimarrà in stato di arresto, e il cmdlet mette questo fuori alla console più e più volte:

[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... 

Alla fine dobbiamo uccidere il servizio nel compito manager, e il nostro script continua quindi.

C'è un modo per fare in modo che il cmdlet di stop-service si arrenda o si esaurisca dopo un certo punto? Immagino che possiamo controllare in seguito e se il servizio è ancora in esecuzione, utilizzare il cmdlet kill-process per fornire un chop finale.

risposta

3

Non esiste un'opzione di timeout per il servizio di arresto, ma se ci sono servizi dipendenti, potrebbe essere necessario utilizzare -force.

I servizi possono definire un suggerimento di attesa (che specifica un timeout) all'avvio, ma il timeout è controllato dal servizio. Qualsiasi richiesta di controllo servizi (avvio, arresto, pausa, ripresa) passa attraverso il gestore controllo servizi (SCM) e rispetterà il suggerimento di attesa per ciascun servizio. Se il suggerimento di attesa viene superato, l'operazione fallirà e verrà restituito un errore.

È possibile utilizzare invoke-command per eseguire Stop-Service come lavoro e controllarlo periodicamente. Se non è stato completato, è possibile utilizzare Stop-Process per terminare il processo e continuare.

+0

Grazie Steven. Penso che questa discussione qui sotto abbia anche dei buoni consigli riguardo all'argomento. In particolare, l'ultimo post sulla pagina: http://www.powershellcommunity.org/Forums/tabid/54/aft/5243/Default.aspx – larryq

+0

Anche questo è un bel po 'di roba. –

7

Sebbene Stop-Service non ha un parametro di timeout, il metodo WaitForStatus sulla classe System.ServiceController ha un sovraccarico che accetta un parametro di timeout (documentato here). Fortunatamente, questo è esattamente il tipo di oggetto restituito dal comando Get-Service.

Ecco una semplice funzione che richiede un nome di servizio e un timeout in secondi. Restituisce $true se il servizio si arresta prima del timeout e $false se la chiamata è scaduta (o se il servizio non è presente).

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 
}