Summary: Microsoft Scripting Guy, Ed Wilson, talks about using Windows PowerShell to troubleshoot non-starting automatic services.
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.
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 firstname.lastname@example.org, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.
Ed Wilson, Microsoft Scripting Guy