Deploying OpsMgr 2012 R2 Agents Using ConfigMgr - Part 2

13 minute read

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))
      IF bFound = FALSE THEN
      'Wscript.Echo "Incorrect management group found. Current Management Group: " & subkey
      bIncorrectMG = TRUE
      END IF
    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
  IF MGName <> MGToAdd THEN
    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
  IF MGName <> MGToAdd THEN
    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.

Leave a comment