Tag Archives: MimboloveSCOM Agent

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.

Deploying OpsMgr 2012 R2 Agents Using ConfigMgr – Part 1

Written by Tao Yang

By reading the title of this article, you may think, this practice is so common, is it worth blogging? Before I started this task, I thought it should be a quick one that I can knock off in 30 minutes. I had to say, I was wrong, I ended up spent few days on it.

Before I get into the details, I’d like to share some background and what I want to achieve. I’ll then go through the steps I took in ConfigMgr 2007 as well ConfigMgr 2012 R2. This is probably going to be too long for one blog post, so I’ll divide it into 2 parts.

I’ll cover the issues that I have experienced when using ConfigMgr 2007 part in part 1. In part 2, I’ll go through how I used the combination of the ConfigMgr 2012 application model and Compliance Settings (DCM) in ConfigMgr 2012 R2 to deploy the OpsMgr 2012 R2 agents.

Background

For the last 9 months or so, I’ve been working on a System Center refresh project. We are in the process of upgrading our existing System Center 2007 infrastructure to System Center 2012 (then we’ve decided to go to R2).

In my employer’s current environment, there are 5 OpsMgr 2007 management groups (1 Dev/Test and 4 Production). Since the supported maximum number of agents per management group has increased from 10,000 to 15,000 in OpsMgr 2012, with the new design for OpsMgr 2012, we are implementing 3 production and 1 Dev/Test management groups. so the agents will be shuffled around, not all agents from a 2007 management group are going to be migrated to the same 2012 management group.

Since ConfigMgr is also going to be migrated to 2012 R2, the OpsMgr 2012 R2 agent needs to be available in both ConfigMgr 2007 and 2012 R2 sites so OpsMgr agents migration can happen either before or after the ConfigMgr client migration. By doing this way, the OpsMgr agent migration is not depended on the result of ConfigMgr migration.

Requirements

Based my situation, I have the following requirements:

  • I need to upgrade the existing OpsMgr 2007 agents and reconfigure them to point to the appropriate 2012 R2 management group.
  • There are no multi-homing agents in my environment. the Old 2007 management group configuration need to be removed from agents.
  • There are large number of legacy systems that don’t have Windows PowerShell installed. So all scripts need to be written using VBScript.
  • The script must work for both upgrade and fresh install scenarios.
  • Back in 2007, I had to create different programs within the package for 32-bit and 64 bit agents. In this script, I want the script to detect the correct msi to install based on OS architecture.
  • Once the 2012 R2 agent is packaged up, it will be used in various OSD task sequences and become a part of the base SOE.

Install Scripts

There are many good scripts for installing OpsMgr 2012 agents out there. i.e. this one here in particular. I used this script as a starting point and made it more generic. I took out any hardcoded management group configuration (Management Group Name, management server, port) and made them as parameters that need to be passed in. I’ve also made the script to get a list of all management groups that agent is connected to and remove any that is not the new 2012 management group that I want the agent to connect.

I tested the script using a command prompt running under LocalSystem account (this can be done using PsExec.exe, “PsExec.exe –s –d –i cmd”)

This command opens a new command prompt window

image

and In task manager, I can confirm it is running under local system:

SNAGHTML1ffa713f

The script ran successfully within the command prompt window under LocalSystem account, the agent was upgraded, new MG configuration is added and the old MG is removed. I then created the package, program in SCCM, and created an advertisement targeting a test collection. After few test runs, I found out the the package only works on Windows Server 2003 or Windows XP machines. any Windows Server 2008 R2 and Windows Server 2012 machines would fail.

Long story short, after I added a logging function within the script, by examining the log, I noticed the script stops right after this line:

Set objMSConfig = CreateObject(“AgentConfigManager.MgmtSvcCfg”)

And this only happens in the more recent Windows OS versions.

I suddenly realised because ConfigMgr 2007 is only 32-bit app, it may have problem calling the 64-bit “AgentConfigManager.MgmtSvcCfg” com object. To prove my guess, I simply created a vbscript with just 2 lines:

Set objMSConfig = CreateObject("AgentConfigManager.MgmtSvcCfg")
Wscript.Echo Err

I then ran it within a 32-bit command prompt window running under LocalSystem account (to simulate the runtime environment in ConfigMgr 2007 client). To do so, again, I used PsExec by using “Psexec.exe –s –d –i C:\Windows\SysWow64\cmd.exe”

image

and my guess is right:

Here’s the error:

Microsoft VBScript runtime error: ActiveX component can’t create object: ‘AgentConfigManager.MgmtSvcCfg’

image

If I run this script in 64-bit command window, there are no errors because Err variable equals 0:

image

So now, I’ve identified the problem being the 64-bit “AgentConfigManager.MgmtSvcCfg” object cannot be called by 32-bit applications. the workaround is fairly simple: I split the original script into 2 scripts. the first script firstly detects the OS architecture and install the appropriate version of MOMAGENT.msi. It then calls the second script to configure the agent using “AgentConfigManager.MgmtSvcCfg” object. The first script detects if itself is running in a 32-bit shell on a 64-bit OS. if so, it would bypass the 32-bit redirection and call the native 64-bit scripting engine cscript.exe using the %Windir%\sysnative\Cscript.exe to execute the second script. So the second script would never be executed within the 32-bit redirection mode.

I’ve named the first script OM12AgentMigration.vbs:

'=============================================
' NAME:    OM12AgentMigration.vbs
' AUTHOR:  Tao Yang
' DATE:    19/11/2013
' Version 1.0.0.1
' COMMENT: OpsMgr 2012 agent migration script
'=============================================
Option Explicit
'ON ERROR RESUME NEXT

'Define variables
Dim objMSConfig, oArgs, OSArch, objWMIService, LogFile, LogFilePath
Dim strInstallCmd, Result, sh, col, arrOSVersion, strOSArch
Dim arrCurrentMGs, arrMGToRemove, iMGToRemoveCount
Dim CurrentMG, strConfigCmd, WinDir, SysnativeDir
Dim item, int64Bit, strPWD, MGCount, arrMGs, MGName, MG
Dim bNewMGAdded, bNewMGExists, bOldMGRemoved, objFSO
Dim MGToAdd, NewMgmtServer, MGToRemove, Port, TempDir
Dim hDefKey, strKeyPath, oReg, arrSubKeys, strSubkey

Const ForWriting = 2
Const ForAppending = 3

'process arguments
Set sh = Wscript.CreateObject("Wscript.Shell")
Set oArgs = Wscript.Arguments

IF oArgs.Count < 2 THEN
	'Quit if no arguments passed in
	Wscript.Quit -1
ELSE
	MGToAdd = oArgs(0)
	NewMgmtServer = oArgs(1)
END IF

If (oArgs.Count = 3 ) Then
	Port = oArgs(2)
Else
	Port = 5723
End If

Set objFSO = CreateObject("Scripting.FileSystemObject")
TempDir = "C:\Temp"

If objFSO.FolderExists(TempDir) = FALSE Then
	objFSO.CreateFolder(TempDir)
End If

LogFilePath = TempDir & "\OM12AgentInstall.log"
Wscript.Echo LogFilePath
'delete previous log file
If objFSO.FileExists(LogFilePath) Then
   objFSO.DeleteFile(LogFilePath)
End If

'Create log file
Set LogFile = objFSO.CreateTextFile(LogFilePath, True)

LogFile.WriteLine "OM12AgentMigration.vbs version: 1.0.0.1"

'Set LogFile = objFSO.OpenTextFile(LogFilePath, ForWriting, True)

strPWD = CreateObject("Scripting.FileSystemObject").GetAbsolutePathName(".")

'Function to determine OS architecture
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

'Get OS architecture so we can determine which version of the agent to install
OSArch = GetOSArch
LogFile.WriteLine "OS Architecture: " & OSArch
'Prepare the agent install command
IF OSArch = "64-bit" THEN
	strInstallCmd = "msiexec /i " & CHR(34) & strPWD & "\AMD64\MOMAgent.msi" & CHR(34) & " /qn AcceptEndUserLicenseAgreement=1 /l*v " & TempDir & "\OM12AgentMSI.log"
	LogFile.WriteLine "64 bit OS detected. Installing OM12 R2 agent using command: '" & strInstallCmd & "'"
ELSEIF OSArch = "32-bit" THEN
	strInstallCmd = "msiexec /i " & CHR(34) & strPWD & "\i386\MOMAgent.msi" & CHR(34) & " /qn AcceptEndUserLicenseAgreement=1 /l*v " & TempDir & "\OM12AgentMSI.log"
	LogFile.WriteLine "32 bit OS detected. Installing OM12 R2 agent using command: '" & strInstallCmd & "'"
END IF

'Determine the command to execute the OM12AgentConfig.vbs script
WinDir = sh.ExpandEnvironmentStrings( "%WinDir%" )
SysnativeDir = WinDir & "\Sysnative"

If objFSO.FolderExists(SysnativeDir) = FALSE Then
	strConfigCmd = WinDir & "\System32\Cscript.exe " & CHR(34) & strPWD & "\OM12AgentConfig.vbs" & CHR(34) & " " & MGToAdd & " " & NewMgmtServer & " " & Port & " " & LogFilePath
Else
	strConfigCmd = WinDir & "\Sysnative\Cscript.exe " & CHR(34) & strPWD & "\OM12AgentConfig.vbs" & CHR(34) & " " & MGToAdd & " " & NewMgmtServer & " " & Port & " " & LogFilePath
End If

'Install agent
Result = sh.run(strInstallCmd,0,True)
If Result <> 0 Then
	LogFile.WriteLine "Failed to install OM12 R2 agent."
	LogFile.Close
	Wscript.Quit -1
Else
	LogFile.WriteLine "Successfully installed the OM12 R2 agent."
End if

LogFile.WriteLine "Start configuring the OM12 R2 agent."
LogFile.WriteLine "Calling OM12AgentConfig.vbs using command: " & strConfigCmd
'Wscript.Echo strConfigCmd
LogFile.Close
Result = sh.run(strConfigCmd,0,True)

The second secript is named OM12AgentConfig.vbs:

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

'ON ERROR RESUME NEXT
Const ForWriting = 2
Const ForAppending = 8

'process arguments
Set sh = Wscript.CreateObject("Wscript.Shell")
Set oArgs = Wscript.Arguments

IF oArgs.Count < 4 THEN
	'Quit if no arguments passed in
	Wscript.Quit -1
ELSE
	MGToAdd = oArgs(0)
	NewMgmtServer = oArgs(1)
	Port = oArgs(2)
	LogFilePath = oArgs(3)
END IF

'Create FSO
Wscript.Echo LogFilePath
set objFSO = CreateObject("Scripting.FileSystemObject")
set LogFile = objFSO.OpenTextFile(LogFilePath, ForAppending, True)

LogFile.WriteLine "Start configuring the OM12 R2 agent."
'Configure OpsMgr 2012 agent
LogFile.WriteLine "Creating AgentConfigManager.MgmtSvcCfg object"
Set objMSConfig = CreateObject("AgentConfigManager.MgmtSvcCfg")

'Get the current MG(s)
LogFile.WriteLine "Getting the configuration for the existing management group(s)."
bNewMGExists = FALSE

Set arrCurrentMGs = objMSConfig.GetManagementGroups()
iCount = 0
For each CurrentMG in arrCurrentMGs
	MGName = CurrentMG.managementGroupName
	IF MGName <> MGToAdd THEN
		LogFile.WriteLine "Removing Management Group: " & MGName
		objMSConfig.RemoveManagementGroup(MGName)
		iCount = iCount + 1
	Else
		LogFile.WriteLine "Skipping management group " & MGName & ", because it's the same as the MG that to be added."
		bNewMGExists = TRUE
	END IF
Next

LogFile.WriteLine "Total number of Management Group(s) Removed: " & iCount

'Add New MG
IF bNewMGExists = FALSE THEN
	LogFile.WriteLine "Adding new management group " & MGToAdd & ". Management server: " & NewMgmtServer & ". Port: " & Port
	Call objMSConfig.AddManagementGroup (MGToAdd, NewMgmtServer,Port)
END IF

'Confirm the new MG has been added
objMSConfig.GetManagementGroup(MGToAdd)
If Err= 0 Then
	bNewMGAdded = TRUE
	LogFile.WriteLine "New MG " & MGToAdd & " added."
Else
	bNewMGAdded = FALSE
	LogFile.WriteLine "New MG " & MGToAdd & " DID NOT get added."
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

LogFile.WriteLine "bNewMGAdded=" & bNewMGAdded
LogFile.WriteLine "bOldMGRemoved=" & bOldMGRemoved
'exit
IF (bNewMGAdded = TRUE AND bOldMGRemoved = TRUE) THEN
	LogFile.WriteLine "OM12 R2 agent installation and configuration successful. reloading the config..."
	Call objMSConfig.ReloadConfiguration
	LogFile.WriteLine "Done."
	LogFile.Close
	Wscript.Quit 0
ELSE
	LogFile.WriteLine "Error installing / configuring OM12 R2 agent"
	LogFile.Close
	Wscript.Quit -1
END IF

When creating the package in ConfigMgr, These 2 scripts need to be copied to the OpsMgr 2012 R2 agent install root folder: SNAGHTML22520a61 The syntax for OM12AgentMigration.vbs is:

cscript /nologo OM12AgentMigration.vbs <Management Group Name> <Management Server FDDN> <Port>

Where the port parameter is optional. when not specified, the default port of 5723 is used. i.e.

cscript /nologo OM12AgentMigration.vbs MYOPSMGRMG  MyManagementServer.MyCompany.com

Both scripts log to a log file located at C:\Temp\OM12AgentInstall.log. When the first script executes msiexec, it also generates a msi log located at C:\Temp\OM12AgentMSI.log. I’ve hardcoded the log files path to C:\Temp rather than using the %temp% environment variable because during my testing in my work’s environment, I have noticed the %temp% variable in some of the machines are incorrectly configured and it would cause the script to fail. my script would create the C:\Temp directory if it does not exist.

The OM12AgentInstall.log looks like this: SNAGHTML225046c7 I have also created an uninstall script called OM12AgentUninstall.vbs, which will work on both 32-bit and 64-bit Operating Systems. This script is also placed on the same folder as the other install scripts.

'=============================================
' NAME:    OM12AgentUninstall.vbs
' AUTHOR:  Tao Yang
' DATE:    22/11/2013
' Version 1.0.0.0
' COMMENT: OpsMgr 2012 agent Uninstall script
'=============================================

MSIGUID64Bit = "{786970C5-E6F6-4A41-B238-AE25D4B91EEA}"
MSIGUID32Bit = "{B4A63055-7BB1-439E-862C-6844CB4897DA}"
Set sh = Wscript.CreateObject("Wscript.Shell")

'Function to determine OS architecture
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

'Get OS architecture so we can determine which version of the agent to install
OSArch = GetOSArch

IF OSArch = "64-bit" THEN
	strUninstallCmd = "msiexec /x " & MSIGUID64Bit & " /qn"
ELSEIF OSArch = "32-bit" THEN
	strUninstallCmd = "msiexec /x " & MSIGUID32Bit & " /qn"
END IF

'Install agent
Wscript.Echo "Uninstalling OM12 agent using command: " & strUninstallCmd
Result = sh.run(strUninstallCmd,0,True)
If Result <> 0 Then
	Wscript.Quit -1
Else
	Wscript.Quit 0
	Wscript.Echo "Successfully uninstalled the OM12 R2 agent."
End if

The syntax for the uninstall script is straightforward:

Cscript /nologo OM12AgentUnisntall.vbs

Packaging in ConfigMgr 2007

I have shown the package source folder structure in previous screenshot. Because only English version of the agent is required in my enviornment, I have removed all the MST’s for other languages in both amd64 and i386 folders. Each folder should only contain 3 files:

agent folder

Because the management group information is passed into the script as parameters, I don’t have to create separate scripts for each OpsMgr 2012 R2 management groups. I created one package for OpsMgr 2012 R2 agents, and then created one install program for each management group and one generic uninstall program:

image

With the install program, here’s how I configured it:

The command line is same as what I mentioned above.

image

Because the script can detect the OS architecture, this program can run on any platform. Also, although the actual size for really small, once the agent start working with the management group, more space is required for the health service stores, downloaded management packs, etc. in my work’s production environment, I checked and the current 2007 R2 agents are using approx. 350MB space. So I specified the estimated disk space to 500MB.

image

The rest of the program properties are pretty normal:

image

image

Note: because this package will be used in OSD task sequences later, I ticked the checkbox as shown above.

Summary

Because of the input parameter difference between OpsMgr 2007 agent and OpsMgr 2012 agent, management group information can longer be passed into the MOMAGENT.MSI during the agent installation. The OpsMgr 2012 (R2) agent needs to be configured using the “AgentConfigManager.MgmtSvcCfg” object. Since the ConfigMgr 2007 is only a 32-bit application, the ConfigMgr 2007 agent on a 64-bit operating system cannot call “AgentConfigManager.MgmtSvcCfg”.

By configuring the OpsMgr 2012 R2 agent package this way in ConfigMgr 2007, I have achieved the following goal:

  • Able to install and configure 64-bit OpsMgr 2012 (R2) agent.
  • No need for multiple programs for 32-bit and 64-bit operating systems.
  • No need to update ConfigMgr package source when the OpsMgr management group changes (i.e. adding / removing management groups, modifying management server names agents reporting to, etc.) because these parameters are passed into the script as command line parameter. In ConfigMgr, these information is stored in the site database rather than within the package source. Therefore I will never have to update distribution points when modifying management group information.
  • The script also removes any management groups that are not the one specified in the parameter, therefore no additional steps required to remove the old 2007 MG information off the agent.
  • As best practice and the company standard, an uninstall program is also created.

Note: DO NOT use my approach on multi-homing OpsMgr agents.

Continue on to Part 2….