How to stop Windows Services via Powershell with AutomaticDelayed start type?

Viewed 277

I was able to write a Powershell 2.0 script that that stops certain running services, which I use in an Ansible script. The Ansible script reboots the VM first, then runs the script.

# Get a list of running XYZ_* services and store them in an array.
$runningExaServices = Get-Service | Where-Object {$_.Name -like "*XYZ_*"} | Where-Object {$_.Status -eq "Running"}

# Iterate throgh the services and stop all of them except EXA_Web,
# EXA_Web_APIs, EXA_Nginx, EXA_Redis. We'll stop those separately
Foreach($service in $runningExaServices) {
    Write-Host "Stopping: "$service.name
    Stop-Service -Name $service.name -Force
    $svc = Get-Service | Where-Object {$_.Name -eq $service.name}
    Write-Host $svc.name: $svc.status
}

The XYZZ_* services will indeed stop. However, the services with Automatic (Delayed Start) would start running again. What's the secret to keeping them stopped? TIA

1 Answers

Since Get-Service doesn't expose the "Automatic (Delayed start)" configuration, you'll have to rely on just the Automatic value for StartType. If you want them to stay stopped, switch the starttype value to "Manual":

# Get a list of running XYZ_* services and store them in an array.
$runningExaServices = Get-Service -Name "*XYZ_*" | Where-Object {$_.Status -eq "Running"} #| Stop-Service -PassThru

Foreach($service in $runningExaServices) {
    #Write-Host "Stopping: $($service.name)"
    if ($service.StartType -eq "Automatic") {
        $Serice | Set-Service -StartupType 'Manual'
    }
    Stop-Service -Name $service.name -Force -PassThru
    # Write-Host "$($svc.name): $($svc.status)"
}

I'm not too sure when these cmdlets were introduced but, I will go ahead and take a guess that Set-Service was released at the same time as Get-Service; i.e. PowerShell 2.0.

With that said, a simple if condition/statement can check for the starttype value and proceed accordingly by setting it to "Manual". Then, stopping the service(s).


Couple of side notes:

  • You don't need the loop if you pipe directly to Set-Service, and Stop-Service given the following circumstances:

    • You don't care about setting the starttype to "Manual"
    • You don't care about the iteration process, and just having them all stop at once with a -PassThru switch provided; which in turn outputs the object with the new status of "Stopped".
  • Lastly, - referring back to the 2nd sub-bullet point above - -PassThru is what I would suggest rather than stating what current service object you're on and re-querying the same object for the new status.

Related