Reputation: 16673
I'm writing a Windows Powershell script that stops a service, then I want to print the service's status when it's finally stopped. I've tried the following, but it just hangs
$service = Get-Service | Where-Object {$_.name -like "*MyService*"}
Stop-Service -Name $service.name
$wait=true
while ($wait) {
if($service.Status -eq "Running") {
Start-Sleep -Seconds 1
}
else {
$wait=$false
}
}
I know I can probably write a for{}
loop instead that counts 0-9, and breaks when my condition is met, but is there a better way?
Upvotes: 1
Views: 1741
Reputation: 437363
tanstaafl's helpful answer addresses your immediate problem:
.Status
property value of a [System.ServiceProcess.ServiceController]
instance (as returned by Get-Service
) is a static value that only reflects the status of the service at the time of the Get-Service
call.[1].Refresh()
method.However, there is no need to explicitly wait for a service to stop, because Stop-Service
is synchronous, i.e.:
-NoWait
.Thus, you can simplify your code as follows:
# Report a script-terminating error if stopping doesn't finish
# within the timeout period.
Stop-Service -Name *MyService* -ErrorAction Stop -WarningAction Stop
More work is needed if you want to implement a retry mechanism.
[1] There is one exception, although the behavior is undocumented and should be considered an implementation detail: If you pipe a preexisting ServiceController
instance to Stop-Service
/ Start-Service
, these cmdlets refresh the instance for you; e.g., after executing ($service = Get-Service Bits) | Stop-Service
, $service.Status
is current (reflects Stopped
).
[2] As of PowerShell Core 7.3.0-preview.2 - see the source code.
Upvotes: 1
Reputation: 190
You need to re-check your service within the loop.
$service = Get-Service | Where-Object {$_.name -like "*MyService*"}
Stop-Service -Name $service.name
$wait=true
while ($wait) {
if($service.Status -eq "Running") {
Start-Sleep -Seconds 1
# ADD THIS BELOW. Need to re-check service in loop.
$service = Get-Service | Where-Object {$_.name -like "*MyService*"}
}
else {
$wait=$false
}
}
Upvotes: 1