Use PowerShell to Find Non-Starting Automatic Services

Summary: Microsoft Scripting Guy, Ed Wilson, talks about using Windows PowerShell to troubleshoot non-starting automatic services.

Hey, Scripting Guy! Question Hey, Scripting Guy! I have this server in a remote office that is running SharePoint. I do not know what version, but I am not certain that is a problem because it used to work. The problem is the workers in this remote office use this SharePoint server every day—they update copies of an Excel spreadsheet that tracks their daily business activity. Anyway, the server is sort of old, and routinely runs with nearly 100 percent of the memory utilized, and 90 percent of the CPU utilized. Today, I got a call from the office manager saying that they cannot access SharePoint. I tried to make a remote desktop protocol (RDP) connection to troubleshoot the machine, but to be honest, with the limited bandwidth and hardware constraints on the machine, RDP creeps me out, and I want to give up in frustration. What I think I need to do is check the status of the services to see what is started, what is not, and if there are any error codes.


Hey, Scripting Guy! Answer Hello DD,

Microsoft Scripting Guy, Ed Wilson, is here. Well today, the weather is balmy … at least I think it is balmy, though not sure exactly what balmy is, so it may not actually be balmy. What the weather does do is remind me of when I was growing up in Florida. The weather outside is 60 degrees Fahrenheit with a humidity of nearly 80 percent. It is not raining, but after spending a bit of time outside, it feels like it will rain. The Magnolia tree in my front yard even has a couple of bloom buds on it, but whether those will turn into flowers or not remains to be seen. So why am I talking retro here? Well DD, it is because to check what you need to check will require you to take a retro-type of approach.

Obtaining service startmode and exit code information

I love using the Get-Service Windows PowerShell cmdlet. In fact, the Get-Service cmdlet is one of the cmdlets I refer to as a “demo” cmdlet. Why demo? Well, because it is so easy to use, and because it returns so much good information. I use it every time I am doing a demonstration of Windows PowerShell for network administrators who have never before seen Windows PowerShell. Luckily, that particular audience pool is rapidly shrinking, and I only occasionally speak to an audience where no one has seen Windows PowerShell previously.

But, three pieces of information commonly required for troubleshooting Windows services are not returned by the Get-Service cmdlet. These three pieces of information are the service StartMode, the service StartName, and  ExitCode. To find these three pieces of information requires using the Win32_Service WMI class.

Finding started and stopped services

DD, you stated that you want to see the StartMode, StartName, and the ExitCode of the services. You also say you want to see what is started and what is not. You can easily get what is started and what is not from the Get-Service cmdlet—in fact, the Get-Service cmdlet takes a ComputerName parameter, and therefore, it might work, depending on the firewall configuration.

By using the Windows PowerShell 3.0 Get-CimInstance cmdlet, the following command returns the service state (what is started and what is not) on a remote computer.

Get-CimInstance win32_service -computer sql1 | Sort state | select name, state

The command and its output associated are shown here.

By using the Windows PowerShell 2.0 cmdlets, the only change required is to change from using the Get-CimInstance cmdlet to using the Get-WmiObject. This command is shown here.

Get-WmiObject win32_service -computer sql1 | Sort state | select name, state

Note   When converting a Get-WmiObject command to Get-CimInstance, keep in mind that the Get-WmiObject cmdlet uses –Class, and Get-CimInstance cmdlet uses –ClassName. But using –Class (or even using it positionally as done in my previous example) works— the problem would be converting a Get-CimInstance cmdlet that had spelled out –ClassName to Get-WmiObject.

Finding start up accounts, exit codes, and startup type

To find information that is more directly related to troubleshooting, it is better to filter out information more directly related to why the service did not start. I am interested in, first, seeing if the service is set to start up automatically and to see if it is, in fact, running. I use the following filter:

-Filter "startmode = 'auto' AND state != 'running'"

Next, I select the name of the service, the startup account used by the service, and the exit code. The command using the Get-Ciminstance cmdlet (along with output associated with the command is shown here.

15:42 C:\> Get-CimInstance win32_service -Filter "startmode = 'auto' AND state != 'running'" -ComputerName sql1 | select name, startname, exitcode

name                         startname                                      exitcode

----                         ---------                                      --------

FIMSynchronizationService                          1066

MSSQLServerADHelper100       NT AUTHORITY\NETWORKSERVICE                        1066

RemoteRegistry               NT AUTHORITY\LocalService                             0

sppsvc                       NT AUTHORITY\NetworkService                           0

SQLAgent$SHAREPOINT          NT AUTHORITY\NETWORK SER...                           0

On Windows PowerShell 2.0, the command is the one showing here.

Get-WmiObject win32_service -Filter "startmode = 'auto' AND state != 'running'" -ComputerName sql1 | select name, startname, exitcode

If a service has an exitcode value of 0, then it means that no error generated when the service exited. For some services, they start, and then stop, and then do not start back up again until they are needed (not all the time, mind you, just some of the time). If I want to hone in on services that do not have an exit code of 0, then I add one more bit of code to my filter. The revised filter is shown here.

-Filter "startmode = 'auto' AND state != 'running' AND Exitcode !=0 "

The complete command is shown here (note, this is a one-line command that is wrapped to display on the blog).

Get-CimInstance win32_service -Filter "startmode = 'auto' AND state != 'running' AND Exitcode !=0 " -ComputerName sql1 | select name, startname, exitcode

Using the Windows PowerShell 2.0 cmdlets, the command is shown here.

Get-wmiobject win32_service -Filter "startmode = 'auto' AND state != 'running' AND Exitcode !=0 " -ComputerName sql1 | select name, startname, exitcode

Both commands and their output are shown here.

DD, that is all there is to using Windows PowerShell to check on the status of Windows Services. Join me tomorrow when I will talk about some more cool Windows PowerShell stuff.

I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

Ed Wilson, Microsoft Scripting Guy

Comments (7)

  1. Anonymous says:

    Even the win32_service class seems to be limited. The property ‘startmode’ returns only 3 values: auto, manual and disabled.
    How can you get all services that have automatic delayed startmode ?

  2. Vern_Anderson says:

    for v2.0 I use…

    Get-WmiObject win32_service | Where-Object -FilterScript { $_.state -ne "Running" -and $_.StartMode -eq "Auto" } | Select-Object name

  3. Ed Wilson says:

    @Vern_Anderson The advantage of using -Filter with Get-WmiObject is that you filter your data on the remote system. Your code returns all of the service information back to your local computer, and then uses the Where-Object to filter through the data. By using -Filter you have WMI on the remote system perform the filtering, and then you only have to process the information you selected. It is more effecient. Of course, if it takes one 20 minutes to construct the appropriate -Filter, then it might be better to use the loose WMI query, and use PowerShell to do the filtering.

  4. oohgodyeah says:

    What single cmdlet can I run to output a Service Name, Status, and Startup Type?  Get-Service only shows me the first two while using Get-WMIObject is missing the current status of the service.  I need to produce output that shows all three just like I see in the GUI.

  5. JV says:

    # get delayed start services
    Get-ChildItem HKLM:SYSTEMCurrentControlSetServices |
    Where-Object {$ -contains "DelayedAutoStart"} |
    Select-Object -ExpandProperty PSChildName


  6. Why can’t I connect to a remote server for this????

    Get-CimInstance : The client cannot connect to the destination specified in the request. Verify that the

    service on the destination is running and is accepting requests. Consult the logs and documentation for

    the WS-Management service running on the destination, most commonly IIS or WinRM. If the destination is

    the WinRM service, run the following command on the destination to analyze and configure the WinRM

    service: "winrm quickconfig".
    At line:1 char:1
    + Get-CimInstance win32_service -ComputerName ANSPP02
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : ConnectionError: (rootcimv2:win32_service:String) [Get-CimInstance], CimExc

    + FullyQualifiedErrorId : HRESULT 0x80338012,Microsoft.Management.Infrastructure.CimCmdlets.GetCimInst

    + PSComputerName : ANSPP02

  7. Wayne Bowser says:

    @Leonard – You’ve probably resolved your issue by now? But you will most likely need to configure the trustedhosts on the remote machine to allow the connection. "Set-Item WSMan:localhostClientTrustedHosts *" using the * accepts all connection requests
    (it’s recommended to replace it with your management PC name.

    For PowerShell to recognize the change to the TrustedHosts settings you will need to restart the WinRM service "Restart-Service winrm"


Skip to main content