Last active
December 11, 2017 15:24
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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