ConfigMgr Debug Logging the Easy Way Using System Center Configuration Manager Compliance Settings

Hello, my name is Cameron Cox, I am a System Center Configuration Manager PFE. For my first blog, I would like to talk about ConfigMgr Compliance Settings. One of the things I have been recommending to my customers more and more is the use of Compliance Settings, and trying to show ConfigMgr admins how useful they can be for day to day task.

Recently one of my customers with a fairly sizable environment (150K Clients) began experiencing backlog issues on a particular site. When we dug into the issue, the Escalation Engineer noted two key findings, disk performance and debug logging were enabled on a remote SQL DB.

The Case for Compliance Settings

After thinking about this for a while, I thought this would be a great use case for Compliance Settings to monitor for debug logging. After playing out the scenario in my head a few times, I thought, what if we could actually enable debug logging with Compliance Settings and disable it once our need for debugging is complete?

In this blog I will cover how to create two Configuration Items with settings to enable and disable debug logging by simply adding/removing a machine from a single collection. Not only will this ensure we have a consistent method to enable debug logging, but it will be apparent if someone leaves a machine in the enable debug collection for an extended period of time. Additionally, we will monitor all clients to ensure debug logging is not enabled manually and left enabled.

Let’s get started!

First we need to create a new CI (Configuration Item). I always recommend a verbose naming convention, not only for the top level CI but for the settings and compliance rules in the CI. In my lab, I named the CI, “CI – ConfigMgr Debug Logging – Enabled.”


 I have no need to exclude this on a per platform basis so I leave the defaults and click next.


 I need to create a new Setting for this CI and I need to give it a name that fits what this particular setting is going to monitor. I give my setting a verbose name, select Script in the first drop down, and Boolean as the second.


  It is worth pointing out, I could do this with the standard Registry Key and Value options but would require multiple settings and compliance rules. In this instance I want to use a script to detect the scenario and return a Boolean data type.

Data type is very important to pay attention to when setting up your CI’s.

When using Compliance Settings, you need to verify the data type you are sending to your compliance rule otherwise the setting will never work properly and will show non-compliant.

Example of this would be looking up a service via WMI (Win32_Service). If I am looking for the “Started” property via PowerShell, the console simply says True. Without verifying the properties via MSDN, you might select the data type of String, and in your compliance rule simply type the word True, but this would be incorrect. The MSDN page shows the started property as a Boolean result, thus the data type should be Boolean. Later, in my detection script, you will see where I use the native PowerShell Boolean output to send my results to the compliance rule.

Enabling Debug Logging

We need to create our detection script to enable debug logging, but how do we enable debug logging for the ConfigMgr client?

A simple Bing search reveals we need to change a couple of values and create a key as well. We need to come up with a standard way of enabling logging, taking in consideration debug logging creates a higher rate of log turn over. In this case, I started on my remediation script first as it will dictate how I detect these settings to know they are enabled.

Remediation Script

Set-ItemProperty -Path Registry::HKLM\SOFTWARE\Microsoft\CCM\Logging\@GLOBAL -name LogLevel -value 0 -ErrorAction SilentlyContinue

Set-ItemProperty -Path Registry::HKLM\SOFTWARE\Microsoft\CCM\Logging\@GLOBAL -name LogMaxHistory -value 2 -ErrorAction SilentlyContinue

New-Item -Path Registry::HKLM\SOFTWARE\Microsoft\CCM\Logging -Name DebugLogging –Force -ErrorAction SilentlyContinue

In my remediation script, I am changing the value of LogLevel and LogMaxHistory, then creating the DebugLogging Key. In order to avoid logs rolling over in production, I recommend changing the value of LogMaxSize as well.

A couple things to note when using PowerShell in Compliance Settings. You need to test your scripts across all the versions of PowerShell existent in your environment. If you have PowerShell 3.0+ dependent commands in your script, and you run it on a PowerShell 2.0 host, you will have errors in your compliance data that are not very easy to track down without enabling debug logging on the ConfigMgr client. Dealing with Compliance Setting errors can sometimes be like finding a needle in a hay stack, but the best place to track errors or problems when rolling out a new Baseline is the Deployments view under the monitoring workspace. There you can find a client with an error to start the troubleshooting process.


Detection Script

Now I can write my detection script.

$Debug2 = Get-ItemProperty -Path Registry::HKLM\SOFTWARE\Microsoft\CCM\Logging\@GLOBAL

$Debug = Test-Path -Path Registry::HKLM\SOFTWARE\Microsoft\CCM\Logging\DebugLogging

IF (($Debug) -and ($Debug2.LogLevel -eq 0) -and ($Debug2.LogMaxHistory -eq 2)) {$True} ELSE {$False}

In my detection script I am pulling in the entire key and properties of HKLM\SOFTWARE\Microsoft\CCM\Logging\@GLOBAL and looking for the existence of the DebugLogging Key. Using an IF statement, I validate the settings and the existence of the new debuglogging key. If all evaluate true, I return the global variable $True to the compliance rule. Note $True is a Boolean data type, thus the reason I selected Boolean for the data type. If one of these items does not return true, $False is sent to the compliance rule and the remediation script will run. In production I would recommend having some more logic around setting the property values. Placing IF statements for the individual settings and only attempting to change the items that are out of compliance. Since I am only doing this in my lab, I am comfortable forcing all the changes.


Now that we have our detection and remediation scripts, we need to test them outside of ConfigMgr. I run my detection script to test my logic.

Now I can test my remediation script then re-run my detection to ensure the settings are set properly and my logic is still valid.


Creating the Compliance Rule

Now that I know the scripts are valid and work outside of ConfigMgr, I can move to creating the Compliance Rule. Since $True is returned when my settings are set properly, I need to ensure True is selected as the returned value. Since I want to remediate, I will check the box to allow remediation.


Disabling Debug Logging

Now I have my first CI to enable debug logging, now I need to create another CI to disable debug logging.

In similar fashion, I have created the remediation script first to determine what I want my detection script to be.

Set-ItemProperty -Path Registry::HKLM\SOFTWARE\Microsoft\CCM\Logging\@GLOBAL -name LogLevel -value 1 -ErrorAction SilentlyContinue

Set-ItemProperty -Path Registry::HKLM\SOFTWARE\Microsoft\CCM\Logging\@GLOBAL -name LogMaxHistory -value 1 -ErrorAction SilentlyContinue

Remove-Item Registry::HKLM\SOFTWARE\Microsoft\CCM\Logging\DebugLogging -force -ErrorAction SilentlyContinue


For my lab I am using the default settings, but this would be a good opportunity to change your logging behavior globally and consistently. Changing the LogMaxHistory to a higher value for more historical logs or changing the value of LogMaxSize depending on how you want setup your default logging scenario.

Now I know what the values should be I can setup my detection script and test outside of ConfigMgr.

$Debug2 = Get-ItemProperty -Path Registry::HKLM\SOFTWARE\Microsoft\CCM\Logging\@GLOBAL

$Debug = Test-Path -Path Registry::HKLM\SOFTWARE\Microsoft\CCM\Logging\DebugLogging

IF (!($Debug) -and ($Debug2.LogLevel -eq 1 -and $Debug2.LogMaxHistory -eq 1)) {$True} ELSE {$False}

Debug logging is still enabled from my last test, so the detection script shows False, once I set the values as they should be it should show true, and it does.

Now to create the CI.

Again when I get to the Settings I use Boolean as the data type and paste in the 2 scripts for detection and remediation.















For the Compliance rule I set it the same way as I did for enabling debug logging.


 Creating Baselines

Now I need to create two baselines: one for the enable rule and one for the disable rule.



Now we need to create two collections so we can deploy these baselines.


Now we can take a look at the way I setup the membership of the disable collection.

I am including the “All Desktop and Server Clients” collection as I want all my ConfigMgr clients to have the same logging setup and to ensure debug logging is not enabled somewhere creating extra overhead. I also exclude my enable collection so when I add a resource to enable debug logging it will remove it from the disable.

Deploying Baselines

Now to deploy my baselines.

Be sure to allow remediation, both in the Compliance Rule and Deployment settings, otherwise our rule will be monitor only. Notice the schedule on the compliance rule, I am running the detection script every 3 hours, this maybe to frequent in a production environment. As a Configuration Manager administrator this would be your call to make, understanding this is a local impact.

I repeat the same for the disable baseline.


There you have it, now you can simply add a machine into the Enable debug collection to enable debug logging. When your testing is complete you can simply remove the machine and know debug logging will be disabled with very little effort.

Thanks for reading!


Comments (5)

  1. Anonymous says:


  2. Anonymous says:

    Great post. Thank you.

  3. Paulo Dias [MSFT] says:

    thanks a lot! very useful!

  4. Terry Wallner says:

    Works as Advertised!

Skip to main content