Possible Stop Cmd Timeout?

We use the stop-service cmdlet to kill several services on our mailboxes. Most of the time it works fine, but we have one or two services (who isn’t?), Which sometimes do not play well.

In this case, one of the services in question will remain in a stopped state, and the cmdlet will display this on the console again and again:

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

In the end, we have to kill the service in the task manager, and then the script.

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

+8
powershell windows-services cmdlet
source share
3 answers

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 determines the timeout) at startup, 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 follow the wait prompt for each service. If the wait hint is exceeded, the operation will fail and an error will be returned.

You can use the invoke command to start Stop-Service as a job and periodically check it. If it is not finished yet, you can use Stop-Process to kill the process and continue.

+3
source share

Although Stop-Service does not have a timeout parameter, the WaitForStatus method in the System.ServiceController class has an overload that accepts 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 timeout in seconds. It returns $true if the service is stopped before the timeout has been reached, and $false if the call has timed out (or if the service is missing).

 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 } 
+7
source share

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 @JamesQMurphy's answer also looks good if you don't have powershell version 5.1.

0
source share

All Articles