Use PowerShell to List Stopped Services that are Set to Start Automatically While Excluding Delayed Start Services

Have you ever had 67 emails about services on your servers being up and down from your monitoring solution? It’s not a good feeling and those emails are only about the ones that monitoring is setup for. What other services could be stopped that aren’t being monitored? Wouldn’t you like a quick and easy way to check whether or not all of the services that are set to start automatically are actually running?

My first thought: Use the Get-Service cmdlet. Unfortunately it doesn’t have a parameter for the Startup Type:

It’s a little more difficult, but what about using WMI via the Get-WMIObject cmdlet? Most of the WMI classes I’ve found useful start with win32 and I’m looking for a service class:

What properties are available when using the WMI Win32_Service class? This looks promising because there’s a StartMode parameter. The only problem is that the BITS service shown in the following image is set to Delayed Start and the StartMode is “Auto”:

WMI can be used to retrieve a list of stopped services that are set to start automatically:

The problem is that all of the services shown in the previous image except one are set to “Automatic (Delayed Start)” as shown in the example in the following image. This causes a sort of false positive because those services aren’t necessarily suppose to be running:

The only way I’ve found to determine if a service is set to “DelayedAutoStart” is in the registry. This property does not exist for services that are not set to “DelayedAutoStart”:

Here’s a list of all the services on my pc that are set to “DelayedAutoStart”:

The first command retrieves a list of stopped services that are set to start automatically. The second one retrieves a list of services that are set to “DelayedAutoStart”. Combine the two so the items returned by the first command that exist in the second one are not returned in the final results:

For the final test, I’ll run this script on 32 servers at the same time:

There are 32 different server names contained in the servers.txt file and it took 3 seconds to complete. Now that’s what I call efficiency and a lot less hassle than 67 emails to look at.



  1. Jeff Wouters

    Hi Mike,
    Now this is a beautifull usecase for ‘workflow’.
    With the following you can get an inventory of such services over your entire environment… needs some target imput tweaking if you want to specify the targets (use get-content or make it into a function and use parameters):

    workflow Get-AutoStoppedServices {
    $Servers = “jeff”,”localhost”
    foreach -parallel ($Server in $Servers)
    $Services = Get-WmiObject -PSComputerName $server -Class Win32_Service -Filter “state = ‘stopped’ and startmode = ‘auto'”
    foreach ($Service in $Services){
    Add-Member -InputObject $Service -MemberType NoteProperty -Name ComputerName -Value $Server
    $Service | select -Property name

    Although I have to say that you wrote a beautifull oneliner 😀


  2. Jeff Wouters

    $Servers = “Jeff”,”localhost” needs to be replaced with Servers = Get-ADComputer *

  3. pamkkkkk

    A really nice article! Well developed!
    I repost it on Google+ and Facebook!
    You can even use Group policies to set the Service states and everything should allways run fine!
    But even then i shoud use a watchdog like that !

    Peter Kriegel

  4. Ernest Brant

    Hello Mike
    I liked the use of the registry search as a condition within the where clause within the overall pipeline cool.
    I some times use [regex] statement within a [regex] statement in a similar manner
    Picked up a little tip here today 🙂


  5. Aydien O'Ryan

    Hi Mike,
    Thanks for this. It is exactly what I require.
    Forgive my daftness though, but I am struggling to see how you are making the connection to the servers remotely in your code.
    Can you help me please?


Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: