Category Archives: SCCM

ConfigMgr OMS Connector

Written by Tao Yang

Earlier this week, Microsoft has release a new feature  in System Center Configuration Manager 1606 called OMS Connector:


As we all know, OMS supports computer groups. We can either manually create computer groups in OMS using OMS search queries, or import AD and WSUS groups. With the ConfigMgr OMS Connector, we can now import ConfigMgr device collections into OMS as computer groups.

Instead of using the OMS workspace ID and keys to access OMS, the ConfigMgr OMS connector requires an Azure AD Application and Service Principal. My friend and fellow Cloud and Data Center Management MVP Steve Beaumont has blogged his setup experience few days ago. You can read Steve’s post here:  As you can see from Steve’s post, provisioning the Azure AD application for the connector can be pretty complex if you are doing it manually – it contains too many steps and you have to use both the old Azure portal ( and the new Azure Portal (

To simplify the process, I have created a PowerShell script to create the Azure AD application for the ConfigMgr OMS Connector. The script is located in my GitHub repository:

In order to run this script, you will need the following:

  • The latest version of the AzureRM.Profile and AzureRM.Resources PowerShell module
  • An Azure subscription admin account from the Azure Active Directory that your Azure Subscription is associated to (the UPN must match the AAD directory name)

When you launch the script, you will firstly be prompted to login to Azure:


Once you have logged in, you will be prompted to select the Azure Subscription and then specify a display name for the Azure AD application. If you don’t assign a name, the script will try to create the Azure AD application under the name “ConfigMgr-OMS-Connector”:


This script creates the AAD application and assign it Contributor role to your subscription:


At the end of the script, you will see the 3 pieces of information you need to create the OMS connector:

  • Tenant
  • Client ID
  • Client Secret Key

You can simply copy and paste these to the OMS connector configuration.

Once you have configured the connector in ConfigMgr and enabled SCCM as a group source, you will soon start seeing the collection memberships being populated in OMS. You can search them in OMS using a search query such as “Type=ComputerGroup GroupSource=SCCM”:


Based on what I see, the connector runs every 6 hours and any membership additions or deletions will be updated when the connector runs.

i.e. If I search for a particular collection based on the last 6 hours, I can see this particular collection has 9 members:


During my testing, I deleted 2 computers from this collection few days ago. If I specify a custom range targeting a 6-hour time window from few days ago, I can see this collection had 11 members back then:


This could be useful sometimes when you need to track down if certain computers have been placed into a collection in the past.

This is all I have to share today. Until next time, enjoy OMS Smile.

Detecting Windows License Activation Status Using ConfigMgr DCM and OpsMgr

Written by Tao Yang

Hello and Happy New year. You are reading my first post in 2015! This is going to a quick post, something I did this week.

Recently, during a ConfigMgr 2012 RAP (Risk and Health Assessment Program) engagement with Microsoft, it has been identified that a small number of ConfigMgr Windows client computers do not have their Windows License activated. The recommendation from the Microsoft ConfigMgr PFE who’s running the RAP was to create a Compliance (DCM) baseline to detect whether the Windows license is activated on client computers.

To respond to the recommendation from Microsoft, I quickly created a DCM baseline with 1 Configuration Item (CI). The CI uses a simple PowerShell script to detect the Windows license status.


I configured the CI to only support computers running Windows 7 / Server 2008 R2 and above (as per the minimum supported OS for the SoftwareLicensingProduct WMI class documented on MSDN:


The CI is configured with 1 compliance rule:


Next, I created a Compliance baseline and assigned this CI to it. I then deployed the baseline to an appropriate collection. after few hours, the clients have started receiving the baseline and completed the first evaluation:


Additionally, since I have implemented and configured the latest ConfigMgr 2012 Client MP (Version, this DCM baseline assignments on SCOM managed computers are also discovered in SCOM, any non-compliant status would be alerted in SCOM as well.


That’s all for today. It is just another example on how to use ConfigMgr DCM, OpsMgr and ConfigMgr 2012 Client MP to quickly implement a monitoring requirement.

Use of ConfigMgr 2012 Client MP: Real Life Examples

Written by Tao Yang

ComplianceLast week, while I was assisting with few production issues in a ConfigMgr 2012 environment, I had to quickly implement some monitoring for some ConfigMgr 2012 site systems. By utilising the most recent release of ConfigMgr 2012 Client management pack (version and few DCM baselines, I managed to achieve the goals in a short period of time. The purpose of this post is to share my experience and hopefully someone can pick few tips and tricks from it.


We are in the process of rebuilding few hundreds sites from Windows Server 2008 R2 / System Center 2007 R2 to Windows Server 2012 R2 / System Center 2012 R2. Last week, the support team has identified few issues during the conversion process. I have been asked to assist. In this post, I will go through 2 particular issues, and also how I setup monitoring so support team and management have a clearer picture of the real impact.

Issue 1: WinRM connectivity issues caused by duplicate computer accounts in AD.

The conversion process involves rebuilding some physical and virtual servers from Windows Server 2008 R2 to Windows Server 2012 R2. When they’ve been rebuilt, they’ve also been moved from Domain A to Domain B (in the same forest) while the computer name remains the same. the support team found they cannot establish WinRM connections to some servers after the rebuild. They got some Kerberos related errors. I had a quick look and found the issue was caused by not having old computer account removed from Domain A, so WinRM using just the NetBIOS name would fail but using FQDN is OK. Although the entire conversion process is automated using Service Manager and Orchestrator, and there is an activity in one of the runbooks deletes old computer accounts, somehow this did not happen to everyone. Moving forward, the support team needs to be notified via SCOM when duplicate computer accounts exists for any computers.

Issue 2: WDS service on ConfigMgr 2012 Distribution Points been mysteriously uninstalled

It took us and Microsoft Premier support few days to identify the cause, I won’t go into the details. But we need to be able to identify from the Distribution Point itself if it is still a PXE enabled DP.

To achieve both goals, I created 2 DCM baselines and targeted them to appropriate collections in ConfigMgr.

Duplicate AD Computer Account Baseline

This baseline contains only 1 Configuration Item (CI). the CI uses a script to detect if the computer account exists in other domains. Here’s the script (note the domain names need to be modified in the first few lines):

In order for the CI to be compliant, the return value from the script needs to be “False” (no duplicate accounts found).



Distribution Point Configuration Baseline

This baseline also only contain 1 CI. Since it contains application setting, I used a very simple script to detect the existence of the ConfigMgr DP:


The compliant condition for the CI is set to:

  • Reg value “HKLM\SOFTWARE\Microsoft\SMS\DP\IsPXE” must exist and set to 1
  • Reg value “HKLM\SOFTWARE\Microsoft\SMS\DP\PXEInstalled” must exist and set to 1



Alerting through OpsMgr

Once I’ve setup and deployed these 2 baselines to appropriate collections, everything has been setup in ConfigMgr. I can now take the ConfigMgr admin hat off.

So what do I need to configure now in OpsMgr for the alerts to go through? The answer is: Nothing! Since the ConfigMgr 2012 Client MP (version has already been implemented in the OpsMgr management group, I don’t need to put on the OpsMgr admin hat because there’s nothing else I need to do. Within few hours, the newly created baselines will be discovered in OpsMgr, and start being monitored:




By utilising the DCM baseline monitoring capability in ConfigMgr 2012 Client MP can greatly simply the processes of monitoring configuration items of targeted endpoints. As showed in these 2 examples, there is no requirement of having OpsMgr administrators involved. Additionally, it is much simpler to create collections for deploying DCM baselines than defining target classes and discoveries in OpsMgr (in order to target the monitors / rules). I encourage you (both ConfigMgr admins and OpsMgr admins) to give it a try, and hopefully you will find it beneficial.

Updated ConfigMgr 2012 (R2) Client Management Pack Version

Written by Tao Yang


It’s only been 2 weeks since I released the last update of this MP (version Soon after the release, Mr. David Allen, a fellow System Center CDM MVP contacted me, asked me to test his SCCM Compliance MP, and possibly combine it with my ConfigMgr 2012 Client MP.

In the ConfigMgr 2012 Client MP, the OVERALL DCM baselines compliance status are monitored by the DCM Agent class, whereas in David’s SCCM Compliance MP, each DCM Baseline is discovered as a separate entity and monitored separately. Because of the utilisation of Cook Down feature, comparing with the approach in the ConfigMgr 2012 Client MP, this approach adds no additional overhead to the OpsMgr agents.

David’s MP also included a RunAs profile to allow users to configure monitoring for OpsMgr agents using a  Low-Privileged default action account.

I think both of the features are pretty cool, so I have taken David’s MP, re-modelled the health classes relationships, re-written the scripts from PowerShell to VBScripts, and combined what David has done to the ConfigMgr 2012 Client MP.

If you (the OpsMgr administrators) are concerned about number of additional objects that are going to be discovered by this release (every DCM baseline on every ConfigMgr 2012 Client monitored by OpsMgr), the DCM Baselines discovery is disabled by default, I have taken an similar approach as configuring Business Critical Desktop monitoring, there is an additional unsealed MP in this release to allow you to cherry pick which endpoints to monitor in this regards.

What’s New in Version

Other than combining David’s SCCM Compliance MP, there are also few other updates included in this release. Here’s the full “What’s New” list:

Bug Fix: ConfigMgr 2012 Client Missing Client Health Evaluation (CCMEval) Execution Cycles Monitor alert parameter incorrect

Added a privileged RunAs Profile for all applicable workflows

Additional rule: ConfigMgr 2012 Client Missing Cache Content Removal Rule

Enhanced Compliance Monitoring

  • Additional class: DCM Baseline (hosted by DCM agent)
  • Additional Unit monitor: ConfigMgr 2012 Client DCM Baseline Last Compliance Status Monitor
  • Additional aggregate and dependency monitors to rollup DCM Baseline health to DCM Agent
  • Additional State View for DCM Baseline
  • Additional instance groups:
    • All DCM agents
    • All DCM agents on server computers
    • All DCM agents on client computers
    • All Business Critical ConfigMgr 2012 Client DCM Agents
  • Additional unsealed MP: ConfigMgr 2012 Client Enhanced Compliance Monitoring
    • Override to enabled DCM baseline discovery for All DCM agents on server computers group
    • Override to disable old DCM baseline monitor for All DCM agents on server computers group
    • Discovery for All Business Critical ConfigMgr 2012 Client DCM Agents (users will have to populate this group, same way as configuring business critical desktop monitoring)
    • Override to enabled DCM baseline discovery for All Business Critical ConfigMgr 2012 Client DCM Agents group
    • Override to disable old DCM baseline monitor for All Business Critical ConfigMgr 2012 Client DCM Agents group
  • Additional Agent Task: Evaluate DCM Baseline (targeting the DCM Baseline class)

Additional icons

  • Software Distribution Agent
  • Software Update Agent
  • Software Inventory Agent
  • Hardware Inventory Agent
  • DCM Agent
  • DCM Baseline


Enhanced Compliance Monitoring

Version has introduced a new feature that can monitor assigned DCM Compliance Baselines on a more granular level. Prior to this release, there is a unit monitor targeting the DCM agent class and monitor the overall baselines compliance status as a whole. Since version, each individual DCM baseline can be discovered and monitored separately.

By default, the discovery for DCM Baselines is disabled. It needs to be enabled on manually via overrides before DCM baselines can be monitored individually.


There are several groups can be used for overriding the DCM Baseline discovery:


Scenario Override Target
Enable For All DCM Agents Class: ConfigMgr 2012 Client Desired Configuration Management Agent
Enable For Server Computers Only Group: All ConfigMgr 2012 Client DCM Agents on Server OS
Enable For Client Computers Only Group: All ConfigMgr 2012 Client DCM Agents on Client OS
Enable for a subset of group of computers Manually create an instance group and populate the membership based on the “ConfigMgr 2012 Client Desired Configuration Management Agent” class

Note: Once the DCM Baseline discovery is enabled, please also disable the “ConfigMgr 2012 Client DCM Baselines Compliance Monitor” for the same targets as it has become redundant.

Once the DCM baselines are discovered, their compliance status is monitored individually:



Additionally, the DCM Baselines have an agent task called “Evaluate DCM Baseline”, which can be used to manually evaluate the baseline. This agent task performs the same action as the “Evaluate” button in the ConfigMgr 2012 client:


ConfigMgr 2012 Client Enhanced Compliance Monitoring Management Pack

An additional unsealed management pack named “ConfigMgr 2012 Client Enhanced Compliance Monitoring” is also introduced. This management pack includes the following:

  • An override to enable DCM baseline discovery for “All ConfigMgr 2012 Client DCM Agents on Server OS” group.
  • An override to disable the legacy ConfigMgr 2012 Client DCM Baselines Compliance Monitor for “All ConfigMgr 2012 Client DCM Agents on Server OS” group.
  • A blank group discovery for the “All Business Critical ConfigMgr 2012 Client DCM Agents” group
  • An override to enable DCM baseline discovery for “All Business Critical ConfigMgr 2012 Client DCM Agents” group.
  • An override to disable the legacy ConfigMgr 2012 Client DCM Baselines Compliance Monitor for “All Business Critical ConfigMgr 2012 Client DCM Agents” group.


In summary, this management pack enables DCM baseline discovery for all ConfigMgr 2012 client on server computers and switch from existing “overall” compliance baselines status monitor to the new more granular compliance baseline status monitor which targets individual baselines. This management pack also enables users to manually populate the new “All Business Critical ConfigMgr 2012 Client DCM Agents” group. Members in this group will also be monitored the same way as the server computers as previously mentioned.

Note: Please only use this management pack when you prefer to enable enhanced compliance monitoring on all server computers, otherwise, please manually configure the groups and overrides as previously stated.


New RunAs Profile for Low-Privilege Environments

Since almost all of the workflows in the ConfigMgr 2012 Client management packs require local administrative access to access various WMI namespaces and registry, it will not work when the OpsMgr agent RunAs account does not have local administrator privilege.

Separate RunAs accounts can be created and assigned to the “ConfigMgr 2012 Client Local Administrator RunAs Account” profile.

RunAs Account Example:


RunAs Profile:


For More information about OpsMgr RunAs account and profile, please refer to:

Note: When assigning a RunAs Account to the “ConfigMgr 2012 Client Local Administrator RunAs Account” profile, you will receive an error as below:


Please refer to the MP documentation section “14.3 Error Received when Adding RunAs Account to the RunAs Profile” for instruction on fixing this error.

New Rule: Missing Cache Content Removal Rule

This rule runs every 4 hours by default and checks if any registered ConfigMgr 2012 Client cache content has been deleted from the file system. When obsolete cache content is detected, this rule will remove the cache content entry from ConfigMgr 2012 client via WMI and generates an informational alert with the details of the missing cache content:


Additional Icons:

Prior to this release, only the top level class ConfigMgr 2012 Client has its dedicated icons. I have spent a lot of time looking for icons for all other classes, I managed to produce icons for each monitoring classes in this release:



Note: I only managed to find high res icons for the Software Distribution Agent and the Software Update Agent (extracted from various DLLs and EXEs). I couldn’t find a way to extract icons from AdminUI.UIResources.DLL – where all the icons used by SCCM are stored. So for other icons, I had to use SnagIt to take screenshots of these icons. You may notice the quality is not that great, but after few days effort trying to find these icons, this is the best I can do. If you have a copy of these icons (res higher than 80×80), or know a way to extract these icons from AdminUI.UIResources.dll, please contact me and I’ll update them in the next release.


BIG thank you to David Allen for his work on the SCCM Compliance MP, and also helping me test this release!

You can download the ConfigMgr 2012 Client MP Version HERE.

Until next time, happy SCOMMING!

How to Create a PowerShell Console Profile Baseline for the Entire Environment

Written by Tao Yang


Often when I’m working in my lab, I get frustrated because the code in PowerShell profiles varies between different computers and user accounts. And your user profile is also different between the normal PowerShell command console and PowerShell ISE. I wanted to be able to create a baseline for the PowerShell profiles across all computers and all users, no matter which PowerShell console is being used (normal command console vs PowerShell ISE).

For example, I would like to achieve the following when I start any 64 bit PowerShell consoles on any computers in my lab under any user accounts:

This is what I want the consoles to look like:



Although I can manually copy the code into the profiles for each of my user accounts and enable roaming profile for  these users, I don’t want to take this approach because it’s too manual and I am not a big fan of roaming profiles.


My approach is incredibly simple, all I had to do is to create a simple script and deployed it as a normal software package  using ConfigMgr. I’ll now go through the steps.

All Users All Hosts Profile

Firstly, there are actually not one (1), but six (6) different PowerShell profiles (I have to admit, I didn’t know this until now Smile with tongue out). This article from the Scripting Guy explained it very well. Based on this article, I have identified that I need to work on the All Users All Hosts profile. Because I want the code to run regardless which user account am I using, and no matter whether I’m using the normal command console or PowerShell ISE.


As I mentioned previously, because I want to use the PSConsole module I have developed earlier, I need to make sure this module is deployed to all computers in my lab. To do so, I have created a simple msi to copy the module to the PowerShell Module’s folder and deployed it to all the computers using ConfigMgr. I won’t go through how I created the msi here.

Code Inside the All Users All Hosts profile

The All Users All Hosts profile is located at $PsHome\profile.ps1


Here’s the code I’ve added to this profile:

if (Get-module -name PSConsole -List)
Import-Module PSConsole

$host.UI.RawUI.BackgroundColor = "Black"
$host.UI.RawUI.ForegroundColor = "Green"
$host.UI.RawUI.WindowTitle = $host.UI.RawUI.WindowTitle + "  - Tao Yang Test Lab"
If ($psISE)
$psISE.Options.ConsolePaneBackgroundColor = "Black"
} else {
Resize-Console -max -ErrorAction SilentlyContinue
set-location C:\

Note: The $psISE variable only exists in the PowerShell ISE environment, therefore I’m using it to identify which console am I currently in and used an IF… Else… statement to control what’s getting executed within PowerShell ISE and normal PowerShell console.

Script To create All Users All Hosts Profile

Next, I have created a PowerShell script to create the All Users All Hosts profile:

# Script Name:        CreateAllUsersAllHostsProfile.ps1
# DATE:               03/08/2014
# Version:            1.0
# COMMENT:            - Script to create All users All hosts PS profile

$ProfilePath = $profile.AllUsersAllHosts

#Create the profile if doesn't exist
If (!(test-path $ProfilePath))
New-Item -Path $ProfilePath -ItemType file -Force

#content of the profile script
$ProfileContent = @"
if (Get-module -name PSConsole -List)
Import-Module PSConsole

<code>$host.UI.RawUI.BackgroundColor = &quot;Black&quot;
</code>$host.UI.RawUI.ForegroundColor = &quot;Green&quot;
<code>$host.UI.RawUI.WindowTitle = </code>$host.UI.RawUI.WindowTitle + &quot;  - Tao Yang Test Lab&quot;
If (<code>$psISE)
</code>$psISE.Options.ConsolePaneBackgroundColor = &quot;Black&quot;
} else {
Resize-Console -max -ErrorAction SilentlyContinue
set-location C:\
#write contents to the profile
if (test-path $ProfilePath)
Set-Content -Path $ProfilePath -Value $ProfileContent -Force
} else {
Write-Error &quot;All Users All Hosts PS Profile does not exist and this script failed to create it.&quot;

As you can see, I have stored the content in a multi-line string variable. The only thing to pay attention to is that I have to add the PowerShell escape character backtick (`)  in front of each variable (dollar sign $).

This script will overwrite the profile if already exists, so it will make sure the profile is consistent across all computers.

Deploy the Profile Creation Script Using ConfigMgr

In SCCM, I have created a Package with one program for this script:


Command Line: %windir%\Sysnative\WindowsPowerShell\v1.0\Powershell.exe .\CreateAllUsersAllHostsProfile.ps1

Note: I’m using ConfigMgr 2012 R2 in my lab, although the ConfigMgr client seems to be 64-bit, this command will still be executed under 32-bit environment. Therefore I have to use “Sysnative” instead of “System32” to overcome 32-bit redirection in 64-bit OS.

I created a re-occurring deployment for this program:


I’ve set it to run it once a day at 8:00am and always rerun.


This is an example on how we can standardise the baseline of PowerShell consoles within the environment. Individual users will still be able to add the users specific stuff in different profiles.

For example, on one of my computers, I have added one line to the default Current User Current Host profile:


In the All Users All Hosts profile, I have set the location to C:\, but in the Current User Current Host profile, I’ve set the location to “C:\Scripts\Backup Script”. The result is, when I started the console, the location is set to “C:\Scripts\Backup Script”. Obviously the Current User Current Host profile was executed after the All Users All Hosts profile. Therefore we can use the All Users All Hosts profile as a baseline and using Current User Current Host profile as a delta Smile.

Packaging OpsMgr 2012 R2 Agent WITH Update Rollup in ConfigMgr 2012

Written by Tao Yang


About 6 months ago, I wrote a 2-part blog series on deploying OpsMgr 2012 R2 agents using ConfigMgr  (Part 1, Part 2). Since then, Update Rollup 1 and Update Rollup 2 has been released. Because UR1 did not include agent updates, I didn’t have to patch any agents. The most recent release of Update Rollup 2 does include agent updates, I’ll have to get the agents patched.

For me, and the project that I’m working on, this is a perfect timing, UR2 was release right before we production transitioning our newly built OpsMgr 2012 R2 management groups and we are just about to start piloting, so I have quickly patched all OpsMgr 2012 R2 management groups with UR2 and from agents point of view, UR2 would now become part of our baseline (for now).

I have determined that the best way for me to incorporate UR2 agent updates to the current agent application in ConfigMgr is to somehow “Slipstream” the update into the agent install. This is due to the size, nature of the environments, and the release management and patch management policies that I can’t comment on.

When I said “Slipstream”, OpsMgr 2012 agents UR updates can’t really be slipstreamed into the agent install msi. So what I have done is to create an application in ConfigMgr that will install the agent AS WELL AS the update.

I’ll now go through the steps I took to setup the ConfigMgr application object.


Note: The steps I took are largely the same as the Part 2 of the original post. I will only go through the changes I have made based on the original package rather than documenting it again from scratch.

01. I firstly duplicated the ConfigMgr source content of the original agent application to another folder.

02. Placed the agent UR2 updates in the AMD64 and i386 folders:





03. Place the newly created “CM12_OM12AgentInstall.vbs” on the root folder:


Note: Please ignore the other 3 scripts in the above screenshot, they were from the 2007 package I created in the original blog post Part 1. They are not required here.

02. created an identical application as described in Part 2 of the original post. -Of course, the application name is changed to something like:


03. Modify the deployment type for the 64 bit machines:

Remove “\AMD64” from the end of the content location field.


Change the installation program from the “msiexec /i ….” to Cscript /nologo CM12_OM12AgentInstall.vbs “64-bit”


04. Modify the 32 bit deployment type the same way as the 64 bit one:

Remove “\i386” from the end of the content location field and change the installation program to Cscript /nologo CM12_OM12AgentInstall.vbs “32-bit”

05. Distribute it to appropriate DP and test it!


The script used for the installation basically installs the MOMAgent.MSI and then UR2 agent update. It can be modified for installing other previous and future agent UR updates by changing the file names on line 59 and 64


When the application is deployed to a ConfigMgr client, the script creates few log files under C:\Temp:


Same as my original post Part 2, the application package does not configure agents to report to any management groups. This is because in my environment, there are multiple management groups, so I am using ConfigMgr Compliance Settings (aka DCM) to configure the agents. this is also documented in the Part 2 of the original post. If you’d like use the same application package to configure the agent, you can simply modify the CM12_OM12AgentInstall.vbs to also combine with the OM12AgentConfig.vbs that I’ve created in Part 1 of the original post. or create a separate application package and specify the dependency between these packages.

Use of Disable Operations Manager alerts option in ConfigMgr

Written by Tao Yang

In System Center Configuration Manager, there is an option “Disable Operations manager alerts while this program runs” in the program within a package:


There are also same options in the deployment of ConfigMgr 2012 applications and Software update groups:

Application Deployment:


Software Update Groups Deployment:


Most of seasoned System Center specialists must already know that these tick boxes do not make the computers enter maintenance mode in OpsMgr. It’s suppressing alerts by pausing the OpsMgr healthservice. As far as I know, there is no way to initiate maintenance mode from an agent. Maintenance mode can only be started from the management server (via Consoles or any scripts / runbooks / applications via SDK).

I am a little bit concerned about enabling these options on deployments targeting OpsMgr management servers. Since I am on holidays this week and have some spare time, I have spent some time in my lab today and performed some tests.

The OpsMgr 2012 R2 management group running in my lab consists of 3 management servers. 2 of which (named OpsMgrMS01 and OpsMgrMS02) are dedicated for managing Windows computers, the 3rd one OpsMgrMS03 is used to manage network devices and UNIX computers. I configured my management group to heartbeat every 60 seconds and allow up to 3 missing heartbeats.

I created a simple batch file to wait 15 minutes and does nothing:


I then created a package and a program in my lab’s ConfigMgr 2012 R2 site, distributed the package to all the distribution points, made sure the “Disable Operations Manager alerts while this program runs” is ticked.

I performed 4 series of the test by deploying this program to different management servers (or combination of management servers):

Test 1: Targeting Single Management Server OpsMgrMS02.

In OpsMgrMS02, there is one agent that hasn’t had failover management servers configured. so I firstly advertised I meant deployed this program to it. When the deployment kicked off, the HealthService entered pause state:


And Event 1217 was logged to the Operations Manager log:


I then waited 15 minutes, I was happy to see that no alerts were logged during this period. I checked few agents who are reporting to OpsMgrMS02, including the one without failover management servers configured. none of them complained about not able to contact the primary management server and no one has failed over to the secondary management servers.

Test 2: Targeting all 3 management servers

I deleted the execution history from OpsMgrMS02’s registry, added the other 2 management servers to the collection in ConfigMgr and then created another mandatory assignment.

3 minutes after the deployment has kicked off on all management servers, I got an alert told me  that the All Management Servers Resource Pool is not available:


I then powered off 2 virtual machines that are monitored in OpsMgr. As expected, I did not get any alerts for these 2 computers while the ConfigMgr deployment was running (because HealthService on all 3 management servers were paused). after 10 minutes or so, they are still not greyed out in the state view:


Soon after the ConfigMgr deployment has finished, the healthservice on all management servers were running again, I got the alerts for the 2 offline agents very shortly because they were still off at that point of time.


I also had a look at a performance view from the Windows Server MP:


I picked a memory counter, the perf collection rule is configured to run every 10 minutes. As you can see from above figure, during the package deployment, the performance data was not collected because there’s 20 minutes apart between 2 readings (supposed to be 10) and the 15-minute deployment falls into the this time window.

Test 3: Targeting OpsMgrMS01

I’ve decided to test on a single MS again. This time I picked the first management server. After the HealthService is paused, I powered off a VM that is reporting to this management server. I was happy to see that the alerts were generated within few minutes (so it should!).

Test 4: Targeting 2 out of 3 Management Servers

For the final test, I targeted OpsMgrMS02 and OpsMgrMS03. Because resource pools require minimum 50% of their members to be healthy. by targeting 2 out of 3 management servers, the All Management Servers Resource Pool became unavailable again. I shutdown 2 virtual machines reporting to OpsMgrMS02. I got the same result as Test 2. alerts were only generated after 15 minutes, when healthservice on 2 management servers have resumed running.


Note: Below recommendations are only based on my PERSONAL experience / opinions:

Based on my tests, I strongly recommend not to use these options during ConfigMgr package / application / software update deployments.

In large organisations, the team who’s using ConfigMgr managing the server fleet is probably not the same people who look after the OpsMgr environments. OpsMgr administrators may not even aware these issues are caused by ConfigMgr deployments because OpsMgr event logs on management servers get filled out fairly quickly. that particular event 1217 may have already been overwritten by the time the OpsMgr administrators are looking for the cause.

By using this option against management servers, you are not only suppressing alerts on for management servers themselves, but also critical alerts (such as computers offline) of the entire management group.

In large management groups, you may get away with just targeting 1 or few management servers because as long as there are more than 50% of management servers running, AMSRP will still be functional. but if your management groups are fairly small (i.e. 2 management servers), you need to be aware that if you pause healthservice on even just 1 MS, AMSRP will be unavailable.

Depending on the nature of the ConfigMgr deployments for your OpsMgr management servers, if no reboots are required, you may want to only select the specific class that is impacted by the deployment to enter the maintenance mode  (i.e. computer role, application components, etc). If reboots are required, make sure failover management servers are configured for all your agents and then disable any alert connectors / subscriptions and stage the reboot process among all your management servers. Nowadays, most likely your management servers will be running on a virtualised platform, so the reboot process should be really quick.

Lastly, I’d like to hear about your opinion. If you have anything to add or disagree with me, please feel free to comment in this post or drop me an email.

ConfigMgr 2012 (R2) Clients Management Pack Released

Written by Tao Yang

ConfigMgr 2012 Client MP IconTime flies, I can’t believe it’s been over 7 months since I posted the beta version of the ConfigMgr 2012 client MP for testing. I haven’t forgotten about this MP (because it’s one of the deliverables for the System Center 2012 upgrade project that I’ve been working on for the last 12 months or so). Today, I finally managed to finish updating this MP, it is ready for final release (Version

I didn’t manage to get many feedbacks since the beta version was released. so it’s either a good thing that everyone’s happy about it, or it’s really bad that no one bothered to use it 🙂 . I would hope it’s because that everyone’s happy about it 🙂

Anyways, below is a list of what’s changed.

Display Name for the ConfigMgr 2012 Client Agents are changed.

in beta version, the display names various client agents(DCM agents, Hardware Inventory agents, etc.) were hardcoded to the client agent name:


I don’t believe it is too user friendly when working in the Operations Console, so in this version, I’ve changed them to be the actual computer name:


Bug Fix: Incorrect Member Monitors for various client agents dependency monitors.

I made a mistake when writing the client agents dependency monitor’s snippet template in VSAE. As the result, all dependency monitors (for availability, performance, configuration and security health) had client agents availability health aggregate monitors as member monitors.


This is now fixed. the correct member monitor is assigned to each dependency monitor.


ConfigMgr 2012 Client object is no longer discovered on cluster instances.

When I was working on the beta version, the development management group that I was using did not have any failover clusters. I didn’t realise the ConfigMgr 2012 Client object is being discovered on cluster instances (virtual nodes) until I imported the MPs into our proper test environment. So this is something that has been overlooked. It is fixed now, it will not discover ConfigMgr 2012 Client (and any client agents) on clusters.

The “ConfigMgr 2012 Client All Programs Service Window Monitor” is now disabled by default.

I’m not too sure how many environments will have a maintenance window (service window) created for all clients. Therefore I’ve disabled this monitor. this is to ensure it will not flood SCOM by generating an alert for each ConfigMgr client. If it is required for all or a subset of ConfigMgr clients, it can be enabled via overrides.

Few spelling mistakes in alerts descriptions are corrected.

Finally, since the beta version was released prior to System Center 2012 R2 release, I have also tested the this MP on ConfigMgr 2012 R2 environment, it is 100% compatible without any modifications.

It can be downloaded HERE. As always, please feel free to contact me if you have any issues or suggestions.

12th April, 2014 Update: Stanislav Zhelyazkov found the override MP packed in the zip file is not correct. It did not have any references to other sealed MP. Not sure what happened when I preparing the zip file. Anyways, If you intend to use the unsealed override MP, please use this one instead.

Configuring System Center Update Publisher 2011 (SCUP) for Multiple Users

Written by Tao Yang

One thing I really don’t like about SCUP 2011 is, the settings are user specific, which means different users will have to manually configure SCUP settings on the same computer. By default, even the SCUP database is stored within the user’s profile. There are already many articles out there on how to change the SCUP database location. (i.e.

Other than the database locations, all other settings such as WSUS connection, SCCM connection, Certificate, source location, etc. are all user based when configured within SCUP Options window:


I figured out an very easy way to make these settings machine-based settings.

To do so,

01. Firstly configure all required settings in the options window as shown above.

02. Browse to “C:\Users\<UserID>\AppData\Local\Microsoft”, locate a folder with the name starts with “Scup2011.exe_StrongName”. i.e.


03. Open above mentioned folder and it’s sub folder, you’ll see a “user.config” file:


04. Open both the “user.config” file as mention above and “<SCUP Install Dir>\Scup2011.exe.config”


05. For each setting in user.config file, locate the same setting in Scup2011.exe.config and copy the value to Scup2011.exe.config


06. Delete the “Scup2011.exe_StrongName_xxxxxxxxx” folder from your profile

07. Open SCUP console, make sure the options are still configured

08. Logon to the SCUP computer with another ID, open SCUP console, confirm the settings are not lost.

Deploying OpsMgr 2012 R2 Agents Using ConfigMgr – Part 2

Written by Tao Yang

This is the 2nd part of 2-part blog series. Part 1 can be found HERE.

In Part 1, I went through the issues I had with deploying OpsMgr 2012 R2 agent via ConfigMgr 2007. In this article, I will go through the steps I took to deploy OpsMgr 2012 R2 agent using ConfigMgr 2012 Application model and Compliance settings (DCM).

Moving to ConfigMgr 2012, I have decided to do utilise the new application model (it’s also to align the policy we set during the design phase of the System Center upgrade project: that wherever is possible, the new application model should be used rather than using the traditional packages / programs in ConfigMgr). By packaging the OpsMgr 2012 R2 agent as an application in ConfigMgr, it is enforced on the ConfigMgr client (i.e. ConfigMgr will automatically install it again if someone manually uninstalled it).


Instead of creating multiple programs within one package for different management groups, I could create different deployment types for different OpsMgr MG’s within the same application. But, because ConfigMgr client will evaluate ALL deployment types in the order I configure using global conditions, it is just going to be way too complex for me to setup global conditions for such a complex OpsMgr environment. Further more, sometimes there are ad-hoc requirements that we also have to move OpsMgr clients among different MG’s for testing and troubleshooting. By using global conditions, this is almost unachievable in my scenario. One way to avoid totally relying on global conditions for the OpsMgr agent application is to create multiple OpsMgr 2012 R2 Agent applications within ConfigMgr 2012 R2, one for each OpsMgr 2012 R2 management group. This is an admin overhead – having to manage and maintain 4 (in my case) almost identical applications for the same purpose.


Because I only want to maintain one application in ConfigMgr for multiple OpsMgr management groups without creating complex global conditions, I have thrown ConfigMgr Compliance Settings (formally known as Desired Configuration Management or DCM) into the mix. The pre-requisite for tis approach is that the Compliance Settings need to be enabled for the ConfigMgr client. This can be done either on the default client setting or creating a custom client setting and deploy it a collection of clients:


Basically, I can separate the OpsMgr agent deployment into 2 steps:

  1. Install OpsMgr 2012 R2 Agent
  2. Configure OpsMgr 2012 R2 Agent to point to the appropriate management group.

By having Compliance Settings in the picture, the application in ConfigMgr will take care of step 1 – installing the agent. And then I create a Compliance Settings Configuration Baseline to ensure the OpsMgr agents are reporting the the correct management group. One good thing about ConfigMgr 2012 is that both applications and configuration baselines are enforced (Configuration Baseline can be configured to auto remediate in 2012, which is not possible in ConfigMgr 2007).

Note: I’m only using this approach because we are managing multiple OpsMgr management groups, if there is only one management group in your environment, this is probably unnecessary and over-complicated.


Firstly, I need to create 2 global conditions for the OpsMgr 2012 R2 agent application. I named them as the following:

  • OS Architecture
  • Is OpsMgr or SCSM Management Server

As the name suggests, the “OS Architecture” Global condition detects the OS architecture using a VBScript which I wrote a long time ago and kept reusing it in many places.



Here’s the script (so you can copy and paste):

Function GetOSArch
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
Set col = objWMIService.ExecQuery _
("Select * from Win32_OperatingSystem")
For Each item in col
arrOSVersion = Split(item.Version,".")
If arrOSVersion(0) >= 6 Then
'OS is Vista / 2008 or higher
StrOSArch = item.OSArchitecture
int64Bit = InStr(item.Caption,"x64")
If int64Bit > 0 Then
strOSArch = "64-bit"
strOSArch = "32-bit"
End If
End If
GetOSArch = strOSArch
End Function
OSArch = GetOSArch
Wscript.Echo OSArch

I also created the second global condition called “Is OpsMgr or SCSM Management Server” to detect if the endpoint is an OpsMgr or SCSM management server. Because OpsMgr agent cannot be install on OpsMgr or Service Manager management servers, they need to be excluded by the application deployment types. This global condition is based on a registry key, if the key HKLM\SOFTWARE\Microsoft\Microsoft Operations Manager\3.0\Server Management Groups exists, the the client is indeed an OpsMgr or Service Manager management server:


Next step is to create the application for OpsMgr 2012 R2 Agent. the “Create Application Wizard” is very straight forward. simply select either the 64-bit or 32-bit MOMAGENT.MSI and the wizard will identify all required information from the MSI.


I have changed the name of the application from “Microsoft Monitoring Agent” to “OpsMgr 2012 R2 agent” as I don’t expect every ConfigMgr operators in my company knows that Microsoft has renamed the OpsMgr agent in the 2012 R2 release.


I have marked my modification in red. Please be aware that the default installation program MUST be changed to:

msiexec /i MOMAgent.msi /qn AcceptEndUserLicenseAgreement=1

AcceptEndUserLicenseAgreement=1 is a required parameter. Without it, the MOMAgent.MSI will not install in quiet mode.

Once the application is created, I created another deployment type for the other OS architecture type. I also renamed both deployment type to reflect the OS architecture:


Now I need to use the two global conditions I created earlier to define requirements for each deployment type.

For 64-bit deployment type, OS Architecture must be equal to “64-bit” and the registry key defined in “Is OpsMgr or SCSM Management Server” must not exist:




Same global conditions needs to apply to the 32-bit deployment type, except OS Architecture must equal to “32-bit”


Now, the application is setup. It can be deployed to a collection. this collection can include every machine needs to be monitored by OpsMgr, AS WELL AS OpsMgr and Service Manager management servers. The global conditions prevent the OpsMgr 2012 R2 Agent from installing on to the OpsMgr or Service Manager servers (even if it tries to install on the management servers, it’s going to fail anyway). The screenshot below indicates the 3 OpsMgr management servers in my lab environment have been excluded (I haven’t built Service Manager 2012 R2 in my lab yet so it’s not on the list):


Note: If a server is in the process to be setup as OpsMgr or Service Manager management server (or Service Manager DW management server), and it is already managed by ConfigMgr, please make sure it is not a member of the collection which the OpsMgr 2012 R2 Agent is deploying to, otherwise OpsMgr 2012 R2 agent might be install prior to the installation of OpsMgr or Service Manager server components and it will cause the server components installation to fail.

Just a side note here:

  • When installing OpsMgr management server, OpsMgr agent MUST NOT be present on the computer.
  • When installing Service Manager management server or Data Warehouse management server, OpsMgr agent MUST NOT be present on the computer.
  • When installing Service Manager web portal server and it will later on be monitored by OpsMgr, the OpsMgr agent MUST be installed prior to the installation of Service Manager web portal. Otherwise, OpsMgr agent cannot be installed after the Service Manager web portal is installed.

Now that the application creation is complete, time to setup Configuration Baseline(s). I will need to setup one configuration item and one configuration baseline for each of the OpsMgr management groups. For the demonstration in this blog post, I’ll only setup one set of configuration item and configuration baseline – for the OpsMgr 2012 R2 management group in my lab.

Firstly, the Configuration Item needs to be created. I named in “OpsMgr 2012 R2 Agent Config CI” in my lab. But in real life, I’ll include the OpsMgr management group name in the Config Item name because is unique to that particular management group.

I’m creating a CI for Windows and it contains application settings:


Next, for the application detection method, I use a VBScript to detect if the healthservice service is present.


Here’s the script (OM12AgentAppCIDetect.vbs):

' NAME:    OM12AgentAppCIDetect.vbs
' AUTHOR:  Tao Yang
' DATE:    26/11/2013
' Version
' COMMENT: Used in ConfigMgr 2012 CI to detect healthservice

bHSFound = FALSE
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
Set colItems = objWMIService.ExecQuery("Select * from Win32_Service Where name = 'healthservice'")
For Each objItem in colItems
bHSFound = TRUE

'Process Result
If bHSFound THEN
Wscript.Echo "Health Service found."
End If

Note: I understand healthservice is also present in OpsMgr and Service Manager management servers. Because the application deployment can be targeting a collection containing OpsMgr or Service Manager management servers, I need to make sure the CI detects the management servers as well, just in case the same collection is used for the Configuration Baselines. If I don’t include management servers in the CI application detect script (i.e. by directly detecting the OpsMgr agent), the Configuration Baseline evaluation result will be Non-Compliant on a management server, which is not a desired result. The script I used in later stage has the smarts to identify management servers.

Next, create a new Setting for the CI:


In the General tab, give setting a name, remember this is unique to the specific OpsMgr management group.

Setting type: Script

Data Type: String

Then add the discovery script and remediation script:


Both scripts are written using VBScript.

Discovery Script (OM12AgentCIDiscovery):


' NAME:    OM12AgentCIDiscovery.vbs
' AUTHOR:  Tao Yang
' DATE:    22/11/2013
' Version
' COMMENT: Used in ConfigMgr 2012 DCM for OpsMgr 2012 R2 agent

'Modify the following line to suit your environment.
AgentMGRegKey= "<Your MG Name>"

function ReadRegistry (strRegistryKey, strDefault )
Dim WSHShell, value

On Error Resume Next
Set WSHShell = CreateObject("WScript.Shell")
value = WSHShell.RegRead( strRegistryKey )

if err.number <> 0 then
ReadRegistry= strDefault
end if

set WSHShell = nothing
end function

Const HKEY_LOCAL_MACHINE = &H80000002

Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")

'01. Check if the OpsMgr or Service Manager management server is installed
Set colItems = objWMIService.ExecQuery("Select * from Win32_Service Where name = 'healthservice'")
bMgmtServer = FALSE
For Each objItem in colItems
'Health Service found. Check if this machine is an OpsMgr or Service Manager management server.
Set oReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\default:StdRegProv")
ServerMGRegKey= "Server Management Groups"
strKeyPath = "SOFTWARE\Microsoft\Microsoft Operations Manager\3.0"
oReg.EnumKey HKEY_LOCAL_MACHINE, strKeyPath, arrSubKeys
For Each subkey In arrSubKeys
bFound = (subkey = ServerMGRegKey)
if bFound then exit for
IF bFound THEN
'OpsMgr or Service Manager management server detected
'Wscript.Echo "OpsMgr or SCSM management server detected."
bMgmtServer = TRUE

'Wscript.Echo "bMgmtServer: " & bMgmtServer

'02. Check if the agent is connected to the correct management group
If bMgmtServer = False Then
'Wscript.Echo "Check Agent's MG config"
Set oReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\default:StdRegProv")
strKeyPath = "SOFTWARE\Microsoft\Microsoft Operations Manager\3.0\Agent Management Groups"
oReg.EnumKey HKEY_LOCAL_MACHINE, strKeyPath, arrSubKeys
bIncorrectMG= FALSE
If Not IsNull(arrSubKeys) Then
For Each subkey In arrSubKeys
bFound = (lcase(subkey) = lcase(AgentMGRegKey))
'Wscript.Echo "Incorrect management group found. Current Management Group: " & subkey
bIncorrectMG = TRUE
bIncorrectMG = TRUE
End IF
End If
'Wscript.Echo "bIncorrectMG: " & bIncorrectMG

'Process Result
bConfigRequired = FALSE
IF bMgmtServer = FALSE THEN
IF bIncorrectMG = TRUE THEN
bConfigRequired = TRUE
'Wscript.Echo "bConfigRequired: " & bConfigRequired
If bConfigRequired = FALSE Then
Wscript.Echo "Compliant"
Wscript.Echo "Non-Compliant"
End If

Please note in the beginning of the script, the variable “AgentMGRegKey” needs to be modified in each environment, it should be the name of the OpsMgr management group.

Remediation Script (OM12AgentRemediate.vbs):


' NAME:    OM12AgentRemediate.vbs
' AUTHOR:  Tao Yang
' DATE:    21/11/2013
' Version
' COMMENT: OpsMgr 2012 agent CI Remediation script


Const ForWriting = 2
Const ForAppending = 8
'Dim arrMGToRemove()
'process arguments
Set sh = Wscript.CreateObject("Wscript.Shell")

MGToAdd = "<Your Management Group Name>"
NewMgmtServer = "<Your Management Server’s FQDN>"
Port = 5723

'Configure OpsMgr 2012 agent
Set objMSConfig = CreateObject("AgentConfigManager.MgmtSvcCfg")

'Get the current MG(s)
bNewMGExists = FALSE
Set arrCurrentMGs = objMSConfig.GetManagementGroups()
'Set arrMGToRemove = CreateObject( "System.Collections.ArrayList" )
For each CurrentMG in arrCurrentMGs
MGName = CurrentMG.managementGroupName
arrMGToRemove.Add MGName
bNewMGExists = TRUE
'iMGToRemoveCount = arrMGToRemove.count

'If iMGToRemoveCount > 0 Then
'    For each item in arrMGToRemove
'        objMSConfig.RemoveManagementGroup(item)
'    Next
'End If

'Add New MG
Call objMSConfig.AddManagementGroup (MGToAdd, NewMgmtServer,Port)

'Confirm the new MG has been added
If Err= 0 Then
bNewMGAdded = TRUE
bNewMGAdded = FALSE
End IF

'Confirm if the newly added MG is the only MG configured on the agent
bOldMGRemoved = TRUE
Set arrMGs = objMSConfig.GetManagementGroups()
For each MG in arrMGs
MGName = MG.managementGroupName
bOldMGRemoved = FALSE

IF (bNewMGAdded = TRUE AND bOldMGRemoved = TRUE) THEN
Call objMSConfig.ReloadConfiguration
Wscript.Quit 0
Wscript.Quit -1

Now, moving to the “Compliance Rule” tab and create a new compliance rule


The Selected Setting should be default to the setting just created.

Rule type: Value

The value returned by the specified script must equal to “Compliant”

Tick the “Run the specified remediation script when this setting is noncompliant” check box

Tick the “Report noncompliance if this setting instance is not found” check box.

For “Noncompliance severity for reports”, I selected “Critical with event”


I unselected “Windows Embedded” under Supported Platforms:


Now that the Configuration Item is created, I need to create a Configuration Baseline.

Again, in real life, I’d name the Configuration Baseline something relevant to the OpsMgr management group it represents. The creation of the Configuration Baseline is pretty straightforward, I need to add the CI I’ve just created to it.


Now, the Configuration Baseline is created, I’ll create a collection that contains all the OpsMgr 2012 R2 agents that SHOULD report to this particular management group, and then deploy the baseline to this collection. When deploying the baseline, make sure the “Remediate noncompliant rules when supported” check box is selected.


Note: In real world, I would create a collection for the OpsMgr agent application deployment, and then create separate collections for each management groups for the Configuration Baslines deployments.

This should be all it’s required. After the OpsMgr 2012 R2 Agent application has been deployed the the endpoint and the Compliance Baseline has arrived to the ConfigMgr client, in my lab, within few hours, the Compliance Baseline got evaluated automatically (during DCM evaluation cycle), and the OpsMgr 2012 R2 client is automatically configured to point to the appropriate management group. The Configuration Baseline should be shown as compliant in the ConfigMgr client:


And when opening “Microsoft Monitoring Agent” in the Control Panel,


you should see the management group you’ve configured in the CI remediation script:


If you want to test the Configuration Baseline, you can simply delete the management group from the Microsoft Monitoring Agent, and then click the “Evaluate” button in ConfigMgr client under “Configuration Tab”. If everything is working as expected, the configuration baseline will show as compliant and the management group is added back to the Microsoft Monitoring Agent.

Note: In the scenarios I mentioned earlier that sometimes when we need to temporarily move OpsMgr agents to different management groups, we will need to modify the collections which the Configuration Baselines are targeting to. To do so, I can firstly create a temp collection to include all OpsMgr agents that I need to move, then exclude this collection from the original Configuration Baseline collection and include it in the Configuration Baseline collection for the target management group. This is so much easier and flexible and we don’t even have to manually move the OpsMgr agents as the Configuration Baseline is going to move them for us.

Note: Please also be aware of the security setting configured for the OpsMgr management group:


If the management group is configured to reject new manual agent installations, you will never see any newly installed & configured OpsMgr agents in the OpsMgr console. You need set it to either automatically approve or review manually installed agents.


By using this method, in an environment with multiple OpsMgr 2012 R2 management group, we can avoid creating multiple applications for OpsMgr 2012 R2 Agent (for different management group) and avoid creating potentially complicated global conditions for the application deployment.

This method also ensures both the OpsMgr 2012 R2 agent installation and configuration is enforced. This prevents anyone with admin access on the endpoint to uninstall OpsMgr 2012 R2 agent or modify it’s configurations.