Monitoring Windows Services States with Log Analytics

Monitoring Windows Services States is one of the most common requests that I’ve seen on forums, groups and blog posts. My fellow MVP and OMS expert Stefan Roth wrote a similar blog post titled OMS – Monitor Windows Services / Processes. I would suggest to check it out as well. The approach I will show is somehow already cover in official article that demonstrates custom fields in Log Analytics. The difference is that we now have the new rich Log Analytics search syntax so we do not need  custom fields anymore. This approach also is different from Stefan’s as his one covers wider topic with monitoring processes by using performance counters. In this approach we will use windows events which Stefan mentions that is not reliable but he was referring to specific Event Id which I also agree it is not reliable. In the next steps I will use another Event Id that is reliable 100%. The advantage of using windows events for monitoring windows services states are:

  • Only windows events are gathered which results in less data uploaded compared to performance data
  • You do not have to add performance counter for each process, you just need to add only one event log to monitor all services

  • The services are shown with their actual name that is used in services.msc or Get-Service cmdlet.

  • We have the actual state of the service when it happened

Some of the disadvantages of this method are:

  • Until the service is started or stopped it will take at least 5 minutes until the data appears in Log Analytics

With that said let’s see how we can achieve this task very easy by using the power of Log Analytics search.

The first we need to do is to add System event log as data source:


If you prefer you can only add Information channel.

The next step is just to execute a query but before that let’s mention what we will do. We will filter on Event Id 7036 from System log. This event contains information which service has stopped or started. That information is contained in EventData column but is unstructured. By using the Log Analytics powerful language we will structure that data very nicely. This is done by executing the following query:


| where EventLog == “System” and EventID == 7036 and Source == ‘Service Control Manager’

| parse kind=relaxed EventData with * ‘<Data Name=”param1″>’ Windows_Service_Name ‘</Data><Data Name=”param2″>’ Windows_Service_State ‘</Data>’ *

| sort by TimeGenerated desc

| project Computer, Windows_Service_Name, Windows_Service_State, TimeGenerated


As you can see from the screenshot we have the Computer in question, the service name, the state – stopped and running when it was started and the time.

Keep in mind this is point in time state and I suggest to automate so that when service is stopped you fire a runbook that starts it. By having the actual name of the service this is pretty easy.

Remember also to filter on the services that you want to monitor because there are a lot of services that start and stop all the time especially on Windows Server 2016.

30 thoughts on “Monitoring Windows Services States with Log Analytics

  1. Great post! Another option is to use the Change Tracking solution, with a query like this one:

    | where ConfigChangeType == “WindowsServices”
    | sort by TimeGenerated desc
    | project Computer, SvcName, SvcState, TimeGenerated

    1. I cannot share the exact runbook but you get the data from Log Analytics – Computer and Service Name. You will have hybrid worker where the remediation work, the hybrid worker will execute the runbook. The runbook will make a PS session to the server and use Get-Service and Start-Service to start it. Simple as that. There is no special magic to the runbook.

    1. Yes,
      It is very simple. You just add a filter on the newly created field Windows_Service_Name. Fill the service name in quotes. Keep in mind that “==” is case sensitive if you want case insensitive you can use “=~”. Any Log Analytics string operators are available for you to filter.

      | where EventLog == “System” and EventID == 7036 and Source == ‘Service Control Manager’
      | parse kind=relaxed EventData with * ‘’ Windows_Service_Name ‘’ Windows_Service_State ‘’ *
      | where Windows_Service_Name == “”
      | sort by TimeGenerated desc
      | project Computer, Windows_Service_Name, Windows_Service_State, TimeGenerated

      1. Thanks for the guide, however only the WMI Performance Adapter Service and Windows Update Service are shown. Should the original query not show all services?
        Also tried the specific service query and entered the service name here: | where Windows_Service_Name == “Custom Servicename”. This however shows not result although the service exists.

        1. Hi,
          With this solution we monitor only the states happening with the services. You will not see all your services there you will only see services when they are stopped or started. If a service hasn’t been stopped or started you will not see it there. When a service is stopped or started there is specific event logged in the System Event Log. We track that event so we know at what specific time service was started or stopped. The query visualizes those actions and can be used for creating alert to monitor if specific service was stopped for example.

  2. i just thinking about scenario service is stopped in multiple computer and i want receive an separate alert for each computer, is there any possibility for this.

    1. Hi
      There is probably problem with copying the query. Unfortunately so far in my blog posts I’ve posted code like any other text and this creates issues with code. When you copy it it there might be empty lines. Remove the empty lines in the query. Also quotes (‘) will not be copied correctly so please remove the quotes and replace them by typing quote sign from your keyboard. I’ve already started using better way to post code in my blog posts.

    1. You can create Log Analytics View to show you the stopped services. Keep in mind that will show you when service was stopped but not if the service is still stopped. You are monitoring the states as described in the article. Preferably you will create alerts and tie them to automation to avoid people manually going to start the services.

      1. Lets rephrase, do you think its possible to make a widget that show the currently stopped services, and not when they have started up again. Maybe with the change tracking logs?
        I’ve been trying to figure out a way to do this, without any succes.

  3. it is obvious that monitoring with an interval of 1 time every 5 minutes, plus the time to send the metrics in Azure, or sending the events of the event log to the Log Analytics is not a useful solution. Since very often the SLA of business services requires a faster response.
    MS need to remove the restriction in 5 minutes or make a separate plan for subscription to send alerts more often.
    What do you think about it? Maybe we have additional tricks in OMS?

  4. Hey, great post. It worked after edtiting the copied code.
    I’ve got results for the different vm’s(6), but both columns “Windows_Service_Name” and “Windows_Service_State” are empty for about 2164 records, in my oppinion it can’t be right. Do you have any suggestions to resolve the problem?

    1. Hi
      I do not know what is your data nor how your modified query looks. Without those two it is hard to provide you an answer. If those fields are not filled you either processing events that are not related to service status events or you are have changed the query so it does not work correctly.

      1. Thank you for your answer. I just removed the empty lines, and replaced the existing quotes with new qoutes at the same location, because I’ve got some syntax error. So, I didn’t change anything important. When I run the query, I just get the name of the vm’s where this events were find and when they were find. If I comment out the “| project” line, I get the name of the services in the “ParameterXml” column.

          1. Event
            | where EventLog == “System” and EventID == 7036 and Source == “Service Control Manager”
            | parse kind=relaxed EventData with * “” Windows_Service_Name “” Windows_Service_State “” *
            | sort by TimeGenerated desc
            | project Computer, Windows_Service_Name, Windows_Service_State, TimeGenerated

            Unfortunatelly, I cannot paste pictures in this this reply. But I get 497 records in four columns “Computer”, “Windows_Service_Name”, “Windows_Service_State” and “TimeGenerated”. “Computer” and “TimeGenerated” have information, but the other two columns are empty.

            1. Sorry, it seems that he didn’t paste the “” into the reply before. It should be, as well as in your query, inside the 2 quotes.

              1. The actual query is

                | where EventLog == ‘System’ and EventID == 7036 and Source == ‘Service Control Manager’
                | parse kind=relaxed EventData with * ” Windows_Service_Name ” Windows_Service_State ” *
                | sort by TimeGenerated desc
                | project Computer, Windows_Service_Name, Windows_Service_State, TimeGenerated

                you have removed the most important part that provides the logic for parsing

  5. I have done with different approach instead of using event data field , I used ‘RenderedDescription’ field. Here it come script.
    | where EventID == 7036 and Source == “Service Control Manager”
    | project RenderedDescription , Computer , EventID , TimeGenerated
    | where RenderedDescription == “The SQL Server (MSSQLSERVER) service entered the stopped state. ”
    | project Computer , EventID , TimeGenerated , RenderedDescription
    | sort by TimeGenerated desc
    | where TimeGenerated >= ago(3h)

    1. Yes that is possible as well but your approach is not very dynamic. The approach I’ve demonstrated is very dynamic as it works for every service possible on windows. With your approach if the SQL server has a named instances the above will not work as the named instance will have different name than MSSQLSERVER.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

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