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).

Challenges

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.

Solution

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:

SNAGHTML23e4be6b

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.

Instructions

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.

SNAGHTML23f734ad

SNAGHTML23f7fe66

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
Else
int64Bit = InStr(item.Caption,"x64")
If int64Bit > 0 Then
strOSArch = "64-bit"
Else
strOSArch = "32-bit"
End If
End If
Next
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:

SNAGHTML23fccf8d

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.

SNAGHTML240076ea

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.

image

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:

image

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:

SNAGHTML24120ed2

SNAGHTML2412e8b8

SNAGHTML2413c79e

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

SNAGHTML2415d9c5

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):

SNAGHTML242a3b1d

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:

image

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

image

Here’s the script (OM12AgentAppCIDetect.vbs):

'=========================================
' NAME:    OM12AgentAppCIDetect.vbs
' AUTHOR:  Tao Yang
' DATE:    26/11/2013
' Version 1.0.0.0
' 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
Next

'Process Result
If bHSFound THEN
Wscript.Echo "Health Service found."
Else
Wscript.quit
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:

SNAGHTML244c4828

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:

image

Both scripts are written using VBScript.

Discovery Script (OM12AgentCIDiscovery):

image

'==============================================
' NAME:    OM12AgentCIDiscovery.vbs
' AUTHOR:  Tao Yang
' DATE:    22/11/2013
' Version 1.0.0.0
' 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
else
ReadRegistry=value
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
Next
IF bFound THEN
'OpsMgr or Service Manager management server detected
'Wscript.Echo "OpsMgr or SCSM management server detected."
bMgmtServer = TRUE
END IF
Next

'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
Next
ELSE
bIncorrectMG = TRUE
End IF
End If
'Wscript.Echo "bIncorrectMG: " & bIncorrectMG

'Process Result
bConfigRequired = FALSE
IF bMgmtServer = FALSE THEN
IF bIncorrectMG = TRUE THEN
bConfigRequired = TRUE
END IF
END IF
'Wscript.Echo "bConfigRequired: " & bConfigRequired
If bConfigRequired = FALSE Then
Wscript.Echo "Compliant"
Else
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):

image

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

'ON ERROR RESUME NEXT

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
objMSConfig.RemoveManagementGroup(MGName)
arrMGToRemove.Add MGName
Else
bNewMGExists = TRUE
END IF
Next
'iMGToRemoveCount = arrMGToRemove.count

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

'Add New MG
IF bNewMGExists = FALSE THEN
Call objMSConfig.AddManagementGroup (MGToAdd, NewMgmtServer,Port)
END IF

'Confirm the new MG has been added
objMSConfig.GetManagementGroup(MGToAdd)
If Err= 0 Then
bNewMGAdded = TRUE
Else
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
END IF
Next

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

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

image

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”

image

I unselected “Windows Embedded” under Supported Platforms:

image

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.

image

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.

image

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:

image

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

SNAGHTML24773e15

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

image

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:

SNAGHTML2480b666

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.

Summary

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.

5 comments on “Deploying OpsMgr 2012 R2 Agents Using ConfigMgr – Part 2

  1. Pingback: Deploying OpsMgr 2012 R2 Agents Using ConfigMgr - Part 1 | Tao Yang's System Management Blog

  2. Hi Tao, i like your aproache but you forgot one thing? maybe it is not needed in your envirorement?!
    I have additional deployment type for AD helper objects with check if computer is DC and OS is only server OS

    • Hi Sergei,
      Thanks for the reply. in my environment, we monitor both servers and workstations, for 3 business units spread across 3 management groups. the MG’s are not separated by business. Some workstations are monitored as business critical desktops and some are not. without going into too much details, it is too hard and inflexible to use global conditions…

  3. Pingback: Packaging OpsMgr 2012 R2 Agent WITH Update Rollup in ConfigMgr 2012 | Tao Yang's System Management Blog

  4. Love the guide Tao! Thank you so much for taking the time to document this. It saved me a bucket load of time in deploying SCOM 2012 R2 agents across our environment.

    A quick comment and improvement suggestion that I found helpful. If you add the following to the remediation script (Insert at line 71, before wscript.quit 0

    ‘Start SCOM Service
    strServiceName = “HealthService”
    Set objWMIService = GetObject(“winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2”)
    Set colListOfServices = objWMIService.ExecQuery (“Select * from Win32_Service Where Name ='” & strServiceName & “‘”)
    For Each objService in colListOfServices
    objService.StartService()
    Next

    This will start the SCOM service once the config has been applied. If this isn’t done, one has to either logon the server and start it manually, or reboot the server to get it started. This is due to it failing to start as it is lacking any configuration to work with when it is installed.

    Hope this might be helpful to you and others!

Leave a Reply