Use PowerShell to Find Non-Starting Automatic Services

Use PowerShell to Find Non-Starting Automatic Services

  • Comments 3
  • Likes

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.

—DD

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    Administrator@iammred.net                          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 scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

Ed Wilson, Microsoft Scripting Guy

Your comment has been posted.   Close
Thank you, your comment requires moderation so it may take a while to appear.   Close
Leave a Comment
  • for v2.0 I use...

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

  • @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.

  • 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.