Create ConfigurationItems and Baselines without killing your mouse

This information applies to ConfigMgr version 1710 and later.

One of the things I really love about working in IT is that you can learn new stuff all the time, and when new stuff turns into boring repetitive stuff you can apply automation and add yet another new piece of learning to your skillset.

Over the last few releases of Configuration Manager, the product team has added some new cmdlets for managing Configuration Items and Baselines, and I started to look into these when I was given the task to create a lot of very similar CIs and Baselines for our excellent dashboard, CTGlobal Insight Analytics.

In order to understand how CI’s work, we should break them down into the components they are built from. A CI is a container for one or more settings. Settings specify what we want to look at, this could be an .exe file, an AD or WMI query, a registry key and so on. For each setting we can then apply one or more rules, that specifies what value the setting should have in order to be compliant.


An example of such a CI could be like the following


This CI has two settings, one that collects the service status for a particular service on SCCM clients using a simple Powershell script, and one that references a specific .exe file.

The rules state that the service must be running, the file must exist and be a specific version.

A variation of this CI is one where the service check is left out, so it would only check for the .exe to exist and that it is at a certain version level, Another variation may be to leave out the version and only check for existence.

All CIs are built from this simple setup but with different settings and rules.

Now that we know how CIs are built lets look into the cmdlets provided with ConfigMgr 1710 that we need in order to create CI’s and Baselines.

  • Get-CMBaseline
  • Remove-CMBaseline
  • Get-CMConfigurationItem
  • Remove-CMConfigurationItem
  • New-CMConfiguration
  • Add-CMComplianceSettingFile
  • Get-CMComplianceSetting
  • New-CMComplianceRuleExistential
  • Add-CMComplianceRule
  • New-CMComplianceRuleVersion
  • Add-CMComplianceSettingScript
  • New-CMComplianceRuleValue
  • New-CMBaseline
  • Set-CMBaseline

Please note that the list of cmdlets for managing CI’s and Baselines is much longer than this list, but these are the ones we need to solve the current challenge.

Our first task is to setup some naming rules

CheckName is the name of the CI and the Baseline that we will create and I set it based on the arguments for the script.

The next step is to remove any existing CI and/or Baseline with that name:

Please note the use of the -Fast switch to avoid loading all the lazy properties of the CI, as this makes thing go a little faster.

Next we will create the new CI:

Note that we need to supply a type of CI, in this case it is WindowsOS (which is all CIs targeting Windows OS)

Next up is creating a Setting for the CI. In the first case, it will be a File setting by the name of “Exe File” and after creating it, we need to get a reference for it for further use:

Note that we pipe in the CI to the cmdlet, as I found that this is the better way to get things to work

The next step is to create the existence rule and if we added a version to the arguments we also build a rule for that:

Again, note the piping of the Setting and CI to the cmdlets.

If we added a service name to the arguments, we also need to setup a setting for a Powershell script to check if the service is running, so let’s do that next:

Note the use of the -NoRule switch when we create the setting, this makes it simpler to separate the individual components in the scripts, and also enables a simple way to add more rules to the script if you wish to do so.

Finally we must create a Baseline and add the CI to it:

Notice that the ID of the CI must be specified using the CI_ID property. Oddly enough, there is no way to add the CI object as an input. This is not a big issue, but would have been a little clearer.

All that is left now is to create a deployment of the Baseline to whatever collection you wish to target. I will not cover that in this blogpost as it is a task we all know and “love”, and of course you can also script your way out of that.

The complete script is available here: Download script

Merry X-Mas or whatever you may celebrate at this time of the year.

By | 2017-12-18T07:32:48+00:00 December 18th, 2017|Automation, Configuration Manager (SCCM), Powershell, Uncategorized|5 Comments

About the Author:

Ronnie Jakobsen
Twitter: @RonnieJakobsen


  1. Richard December 18, 2017 at 16:27 - Reply

    Thanks for the great information and blog!, I wondered if you have been able to successfully tick the remediate checkbox using PowerShell.
    More info:

  2. Ronnie Jakobsen
    Ronnie Jakobsen December 19, 2017 at 12:13 - Reply

    I have tried but with no luck, I can add the remediate script and values to check for, but not the checkbox

    I always get this message when trying to set Remediate “The parameter ‘Remediate’ has been ignored because one or more conditions for its use have not been met.”

  3. Ronnie Jakobsen
    Ronnie Jakobsen December 19, 2017 at 13:19 - Reply

    It is not very pretty but it does the trick

    Do this AFTER you add the rule to the settings

    $rule = $ci |Get-CMComplianceRule -RuleName “Name of the rule”
    $rule.Expression.Operands[0].IsChangeable = $true
    $ci | Remove-CMComplianceRule -RuleName “Name of the rule” -Force
    $temp = $ci | Add-CMComplianceSettingRule -Rule $rule

  4. Richard December 19, 2017 at 15:11 - Reply

    Thanks for your time Ronnie and for the work around! Your suggestion works perfectly.

    I have logged the issue on connect so hopefully it will get fixed soon. (reference 3145396)

  5. Richard December 22, 2017 at 9:54 - Reply

    The bug has just been marked as fixed, here is hoping to see it in the version version or 2.

Leave A Comment