Skip to content

Instantly share code, notes, and snippets.

@ctigeek
Last active December 11, 2017 15:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ctigeek/c57fb9693a5851ddc564ebc58e2850ac to your computer and use it in GitHub Desktop.
Save ctigeek/c57fb9693a5851ddc564ebc58e2850ac to your computer and use it in GitHub Desktop.
Stop a windows service. Wait for the process to die. Option to kill it if it doesn't stop.
function Stop-ServiceAndWaitForItToDie {
[cmdletbinding()]
Param(
[Parameter(Mandatory=$True,ValueFromPipeline=$True)]
[object] $Service,
[Parameter(Mandatory=$False,ValueFromPipeline=$False)]
[int] $TimeoutInSeconds = 30,
[Parameter(Mandatory=$False,ValueFromPipeline=$False)]
[Switch] $KillAfterTimeout,
[Parameter(Mandatory=$False,ValueFromPipeline=$False)]
[Switch] $Force
)
BEGIN {
if ($TimeoutInSeconds -lt 0) { throw "TimeoutInSeconds must be greater than zero." }
}
PROCESS {
if (-not $Service) { return; }
$serviceName = $Service.Name
$serviceProcessId = Get-WmiObject -Class Win32_Service -Filter "Name LIKE '$serviceName'" | Select-Object -ExpandProperty ProcessId
if ($serviceProcessId -eq 0) { return; }
Write-Host "Stopping service $serviceName with process ID #$serviceProcessId"
Stop-Service $serviceName -ErrorAction SilentlyContinue -Force:$Force
$process = $null
$process = Get-Process -Id $serviceProcessId -ErrorAction SilentlyContinue
$totalTime = [System.TimeSpan]::FromSeconds(0)
while ($process) {
Write-Debug "$totalTime and $($process.FileName)"
if ($process.WaitForExit(100)) {
Write-Debug "Service $serviceName is now stopped."
}
$totalTime = $totalTime.Add([System.TimeSpan]::FromMilliseconds(100))
if ($totalTime.TotalSeconds -gt $TimeoutInSeconds) {
if ($KillAfterTimeout) {
Write-Warning "Process for $serviceName did not shut down. Killing it..."
Stop-Process -Id $serviceProcessId -Force:$Force
Start-Sleep -Milliseconds 3000
##Is it starting back up?
$Service = $null
$Service = Get-Service $serviceName -ErrorAction SilentlyContinue
if ($Service -and $Service.Status -ne [System.ServiceProcess.ServiceControllerStatus]::Stopped) {
while ($Service.Status -eq [System.ServiceProcess.ServiceControllerStatus]::StartPending) {
Start-Sleep -Milliseconds 100
$Service.Refresh()
}
$serviceProcessId = Get-WmiObject -Class Win32_Service -Filter "Name LIKE '$serviceName'" | Select-Object -ExpandProperty ProcessId
$Service | Stop-ServiceAndWaitForItToDie -TimeoutInSeconds 10 -Force
}
}
$process = $null
$process = Get-Process -Id $serviceProcessId -ErrorAction SilentlyContinue
break
}
$process = $null
$process = Get-Process -Id $serviceProcessId -ErrorAction SilentlyContinue
}
if ($process) {
throw "Could not stop the service. Nuke it from space."
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment