2012-09-21 12 views
8

Estamos usando el cmdlet stop-service para eliminar algunos servicios en nuestros cuadros. La mayoría de las veces funciona muy bien, sin embargo, tenemos uno o dos servicios (¿quién no?) Que ocasionalmente no funcionan bien.stop-service cmdlet timeout possible?

En este caso uno de los servicios en cuestión permanecerá en el estado de parada, y el cmdlet pone esto a la consola una y otra vez:

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

Finalmente tenemos que matar el servicio en la tarea gerente, y nuestro guión luego continúa.

¿Hay alguna manera de que el cmdlet stop-service se pierda o supere el tiempo después de cierto punto? Supongo que podemos verificarlo luego y si el servicio aún se está ejecutando, use el cmdlet kill-process para proporcionar un corte final.

Respuesta

3

No hay opción de tiempo de espera para detener el servicio, pero si hay servicios dependientes, es posible que necesite usar -force.

Los servicios pueden definir una pista de espera (que especifica un tiempo de espera) cuando comienzan, pero el tiempo de espera es controlado por el servicio. Cualquier solicitud de control de servicio (inicio, detención, pausa, reanudación) pasa por el administrador de control de servicio (SCM) y respetará la sugerencia de espera para cada servicio. Si se excede la indicación de espera, la operación fallará y se devolverá un error.

Puede usar invoke-command para ejecutar Stop-Service como un trabajo y verificarlo periódicamente. Si no se ha completado, puede usar Stop-Process para matar el proceso y continuar.

+0

Gracias Steven. Creo que esta discusión a continuación también tiene algunos buenos consejos con respecto al tema. En particular, la última publicación en la página: http://www.powershellcommunity.org/Forums/tabid/54/aft/5243/Default.aspx – larryq

+0

Eso también es algo bueno. –

7

Aunque Stop-Service no tiene un parámetro de tiempo de espera, el método WaitForStatus en la clase System.ServiceController tiene una sobrecarga que toma un parámetro de tiempo de espera (documentado here). Afortunadamente, este es exactamente el tipo de objeto que devuelve el comando Get-Service.

Aquí hay una función simple que toma un nombre de servicio y un tiempo de espera en segundos. Devuelve $true si el servicio se detiene antes de que se agote el tiempo de espera y $false si la llamada expira (o si el servicio no está 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 
}