stop-service cmdlet timeout possible?

14,647

Solution 1

There is no timeout option for stop-service, but if there are dependent services, you may need to use -force.

Services can define a wait hint (which specifies a timeout) when they start, but the timeout is controlled by the service. Any service control requests (start, stop, pause, resume) go through the service control manager (SCM) and will respect the wait hint for each service. If the wait hint is exceeded, the operation will fail and an error be returned.

You could use invoke-command to run Stop-Service as a job and check it periodically. If it hasn't completed, you could use Stop-Process to kill the process and continue.

Solution 2

Although Stop-Service does not have a timeout parameter, the WaitForStatus method on the System.ServiceController class does have an overload that takes a timeout parameter (documented here). Fortunately, this is exactly the type of object that the Get-Service command returns.

Here is a simple function that takes a service name and a timeout in seconds. It returns $true if the service stops before the timeout is reached, and $false if the call times out (or if the service isn't present).

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
}

Solution 3

If you have powershell 5.1 you also have :

Stop-Service -Name "NameOfService" -NoWait

https://msdn.microsoft.com/en-us/powershell/reference/5.1/microsoft.powershell.management/stop-service

But answer of @JamesQMurphy looks good too, if you don't have the 5.1 version of powershell.

Share:
14,647

Related videos on Youtube

larryq
Author by

larryq

Updated on July 01, 2022

Comments

  • larryq
    larryq almost 2 years

    We're using the stop-service cmdlet to kill a few services on our boxes. Most of the time it works great, however we have one or two services (who doesn't?) that occasionally don't play nice.

    In this instance one of the services in question will remain in the stopping state, and the cmdlet puts this out to the console over and over:

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

    Eventually we have to kill the service in the task manager, and our script then continues.

    Is there a way to have the stop-service cmdlet give up or timeout after a certain point? I figure we can check afterward and if the service is still running, use the kill-process cmdlet to provide a final chop.

  • larryq
    larryq over 11 years
    Thanks Steven. I think this discussion below also has some good advice regarding the subject. In particular, the last posting on the page: powershellcommunity.org/Forums/tabid/54/aft/5243/Default.asp‌​x
  • Cardin
    Cardin over 5 years
    Doesn't answer the question, which had a requirement of give up or timeout after a certain point. Asynchronous termination is not the same as wait for timeout.
  • ojintoad
    ojintoad over 3 years
    I think this is a suggestion of an easier way to accomplish the stop-service and wait pattern that JamesQMurphy suggests.