in some occasions you don't want to have the APM module installed at all because it can break IIS - if one of the Application Pools is using .NET 2.0 (
Technet article)
pushing the agent via SCOM will always install also the APM module.
so I created a script which will uninstall the SCOM agent, and then reinstall it without APM.
reason for the uninstall is, I tried to do a repair as they suggest, however, the repair fails - complaining it is missing some data - I presume this is related to the fact that after installing the agent UR1 was applied, so the MOMAgent.msi that I was using is the base version without UR1.
obviously if you use the SCOM agent to reinstall itself, it has to launch a script which is independent of the SCOM agent, so the process uses a VBscript which creates a commandfile and then registers a
runonce scheduled task to run 2 minutes later....
I have registered the task against the Agent class
The script task requires 2 parameters :
(I have shared out the AgentManagement folder to everyone read-only)
first find in the registry where the uninstall string is located, and /I or /X are replaced with /qn /X
then scan the registry for the installed management groups, and store them into an array
MGNames(x), MGservers(x), MGports(x)
so the script collects that information, and then creates a batch file (first as txt file).
you have to create it as txt because security does not permit to create a .cmd directly....
the batchfile contains the following steps (each separated by a ping command as "sleep")
- copy Agent install files
- uninstall agent (UninstallString)
- Install agent with PrimaryManagementgroup
the management server is pulled from the registry prior to uninstall
- install URx update
- if detected, a VBscript is executed to add it to the extra management groups
- delete the folder (rd /s /q folder) and it's contents
besides the batchfile, if the agent was registered to more than 1 management group, for every extra management group, it creates a VBscript to register the extra management group
so this is what the batchfile looks like that is created by the task
xcopy
\\MGserver\Agentmanagement\amd64\* C:\windows\temp\amd64 /Y /R
ping 1.1.1.1 -n 10 /w 1000 > nul
MsiExec.exe /qn /X {742D699D-56EB-49CC-A04A-317DE01F31CD}
ping 1.1.1.1 -n 70 /w 1000 > nul
msiexec.exe /qn /i c:\windows\temp\amd64\Momagent.msi USE_SETTINGS_FROM_AD=0 ACTIONS_USE_COMPUTER_ACCOUNT=1 USE_MANUALLY_SPECIFIED_SETTINGS=1 MANAGEMENT_GROUP=
MGgroup MANAGEMENT_SERVER_DNS=
MGServer NOAPM=1 SECURE_PORT=
MGport AcceptEndUserLicenseAgreement=1
ping 1.1.1.1 -n 70 /w 1000 > nul
msiexec.exe /p c:\windows\temp\amd64\KB3190029-amd64-Agent.msp
ping 1.1.1.1 -n 70 /w 1000 > nul
cscript.exe C:\windows\temp\amd64\
AddMGgroup0.vbs
ping 1.1.1.1 -n 20 /w 1000 > nul
rd /s /q C:\windows\temp\amd64
and this is what the VBscript looks like that is created by the task:
Set objMSConfig = CreateObject("AgentConfigManager.MgmtSvcCfg")
Call objMSConfig.AddManagementGroup(
MGname,MGServer,MGport)
If Err.number <> 0 Then
wscript.echo ("Failed to add SCOM")
Else
Set oShell = WScript.CreateObject("WScript.Shell")
Set oAPI = CreateObject("MOM.ScriptAPI")
set oShellEnv = oShell.Environment("Process")
computerName = oShellEnv("ComputerName")
strCommand = "cmd /c net stop HealthService & cmd /c net start HealthService"
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
Set objProcess = objWMIService.Get("Win32_Process")
Set objProgram = objProcess.Methods_("Create").InParameters.SpawnInstanceobjProgram.CommandLine = strCommand
Set strShell = objWMIService.ExecMethod("Win32_Process", "Create", objProgram)
wscript.echo ("Management Group SCOM has been added")
WScript.echo "Restarting SCOM Health Service on " & computerName
End If
so the above 2 files are created by the following task in SCOM (run at the agent)
on error resume next
Const HKLM = &H80000002 'HKEY_LOCAL_MACHINE
Dim oParams, strComputer, strKey, sourcefolder, Destinationfolder, VBfilename, CMDFile, delay
Dim FSO, objReg, strSubkey, arrSubkeys, wshShell,MGServer, MGServer1
Dim DisplayName, UninstallString, InstallString
Set oParams = WScript.Arguments
PrimaryMG = trim(oParams(0)) 'Management Group that should be registered again
AgentSourcePath = trim(oParams(1)) 'path to share and folder where Agent Install files can be found
Set oShell = wscript.CreateObject ("wscript.Shell")
set fs = CreateObject("Scripting.FileSystemObject")
strWindows = oShell.ExpandEnvironmentStrings("%windir%")
OutFolder = strWindows & "\temp\amd64"
Outputfile = strWindows & "\temp\amd64\OpsNoAPM.txt"
oShell.LogEvent 4, "OpsNoAPM.cmd: Going to create " & Outputfile
strComputer = "."
strKey = "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\"
'Get WMI object
Set objReg = GetObject("winmgmts://" & strComputer & "/root/default:StdRegProv")
objReg.EnumKey HKLM, strKey, arrSubkeys
'Loop registry key to find uninstall string for SCOM Agent
For Each strSubkey In arrSubkeys
objReg.GetStringValue HKLM, strKey & strSubkey, "DisplayName" , DisplayName
If Instr(DisplayName,"Microsoft Monitoring Agent") > 0 Then
objReg.GetStringValue HKLM, strKey & strSubkey, "UninstallString", UninstallString
if (instr(UninstallString,"/I") > 0 ) then
UninstallString = replace(UninstallString,"/I","/qn /X ")
Elseif (instr(UninstallString,"/X") > 0 ) then
UninstallString = replace(UninstallString,"/X","/qn /X ")
Else
wscript.echo "no uninstall string found"
wscript.quit
end if
End If
Next
'loop registry to retrieve all management groups
strKey = "SOFTWARE\Microsoft\Microsoft Operations Manager\3.0\Agent Management Groups\"
Set objReg = GetObject("winmgmts://./root/default:StdRegProv")
objReg.EnumKey HKLM, strKey, arrSubkeys
Dim arrMGGroups()
Dim arrMGservers()
Dim arrMGPorts()
size = Ubound(arrSubkeys)
Redim arrMGGroups(size)
Redim arrMGservers(size)
Redim arrMGPorts(size)
cnt = 0
For Each strSubkey In arrSubkeys
arrMGGroups(cnt) = strSubkey
objReg.GetStringValue HKLM, strKey & strSubkey & "\Parent Health Services\0", "NetworkName", MGServer
objReg.GetDWORDValue HKLM, strKey & strSubkey & "\Parent Health Services\0", "Port", MGPort
arrMGservers(cnt) = MGServer
arrMGPorts(cnt) = MGPort
cnt = cnt + 1
next
if NOT isnull(UninstallString) then
if fs.FolderExists(OutFolder) then
if fs.FileExists(Outputfile) then fs.DeleteFile(OutputFile)
if fs.FileExists(ResultFile) then fs.DeleteFile(ResultFile)
Else
fs.CreateFolder(OutFolder)
End if
'Create batchfile to uninstall+install+patch+register extra MG group(s)
Set out = fs.CreateTextFile(Outputfile)
out.writeline "xcopy " & AgentSourcePath & "\* " & outFolder & " /Y /R"
out.writeline "ping 1.1.1.1 -n 10 /w 1000 " & chr(62) & " nul"
out.writeline UninstallString
out.writeline "ping 1.1.1.1 -n 70 /w 1000 " & chr(62) & " nul"
'register back with the same management server
for x = 0 to size
if arrMGGroups(x) = PrimaryMG then
MGServer1 = arrMGservers(x)
MGPort = arrMGPorts(x)
end if
next
out.writeline "msiexec.exe /qn /i c:\windows\temp\amd64\Momagent.msi USE_SETTINGS_FROM_AD=0 ACTIONS_USE_COMPUTER_ACCOUNT=1 USE_MANUALLY_SPECIFIED_SETTINGS=1 MANAGEMENT_GROUP=" & PrimaryMG & " MANAGEMENT_SERVER_DNS=" & MGServer1 & " NOAPM=1 SECURE_PORT=" & MGPort & " AcceptEndUserLicenseAgreement=1"
out.writeline "ping 1.1.1.1 -n 70 /w 1000 " & chr(62) & " nul"
out.writeline "msiexec.exe /p c:\windows\temp\amd64\KB3190029-amd64-Agent.msp"
out.writeline "ping 1.1.1.1 -n 70 /w 1000 " & chr(62) & " nul"
'create VBscript that will register any other management groups and add line to commandfile to execute the VBscript
for x = 0 to size
if arrMGGroups(x) <> PrimaryMG then
VBfilename = outfolder & "\AddMGgroup" & x
'create unique VBfile to register extra MGgroup
AddMGgroup arrMGGroups(x), arrMGservers(x), arrMGPorts(x), VBfilename
out.writeline "cscript.exe " & VBfilename & ".vbs"
out.writeline "ping 1.1.1.1 -n 20 /w 1000 " & chr(62) & " nul"
end if
next
out.writeline "rd /s /q " & OutFolder
out.close
wscript.sleep(1000)
'rename text file to .CMD
CMDFile = Replace(right(Outputfile,len(Outputfile) - instrrev(Outputfile,"\")),"txt", "cmd")
oShell.run "CMD /C rename " & Outputfile & " " & CMDFile, 0, true
wscript.echo "Renamed " & outputfile & " to " & CMDFile
delay = 3
oShell.run "cmd /c %windir%\system32\schtasks.exe /create /RU SYSTEM /RL HIGHEST /V1 /Z /F /sc ONCE /st " & formatdatetime(dateadd("N",delay,now()),VBShortTime) & " /TN SCOMAgentUpdate /tr " & OutFolder & "\" & CMDFile
info = "OpsNoAPM.cmd: created OpsNoAPM.cmd - it's scheduled to run at " & formatdatetime(dateadd("N",delay,now()),VBShortTime)
oShell.LogEvent 4, info
wscript.echo info
Else
info = "OpsNoAPM.cmd: no registry entry found with the install location of the SCOM agent"
oShell.LogEvent 4, info
wscript.echo info
end If
Set oShell = Nothing
set out = Nothing
set fs = Nothing
'subroutine to create VBscript file to register an extra management group
sub AddMGgroup (MGName, MSNAme, MGPort,VBfile)
dim VBf
Set VBf = fs.CreateTextFile(VBfile & ".txt")
VBf.writeline "Set objMSConfig = CreateObject(""AgentConfigManager.MgmtSvcCfg"")"
VBf.writeline "Call objMSConfig.AddManagementGroup(" & MGName & "," & MSNAme & "," & MGPort & ")"
VBf.writeline "If Err.number <> 0 Then"
VBf.writeline " wscript.echo (""Failed to add " & MGName & """)"
VBf.writeline "Else"
VBf.writeline " Set oShell = WScript.CreateObject(""WScript.Shell"")"
VBf.writeline " Set oAPI = CreateObject(""MOM.ScriptAPI"")"
VBf.writeline " set oShellEnv = oShell.Environment(""Process"")"
VBf.writeline " computerName = oShellEnv(""ComputerName"")"
VBf.writeline " strCommand = ""cmd /c net stop HealthService & cmd /c net start HealthService"""
VBf.writeline " Set objWMIService = GetObject(""winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2"")"
VBf.writeline " Set objProcess = objWMIService.Get(""Win32_Process"")"
VBf.writeline " Set objProgram = objProcess.Methods_( _"
VBf.writeline " ""Create"").InParameters.SpawnInstance_"
VBf.writeline " objProgram.CommandLine = strCommand"
VBf.writeline " Set strShell = objWMIService.ExecMethod(""Win32_Process"", ""Create"", objProgram)"
VBf.writeline " wscript.echo (""Management Group " + MGName + " has been added"")"
VBf.writeline " WScript.echo ""Restarting SCOM Health Service on "" & computerName"
VBf.writeline "End If"
VBf.close
vbFile1 = right(VBFile,len(VBFile) - instrrev(VBFile,"\")) & ".vbs"
wscript.echo "CMD /C rename " & VBfile & ".txt " & VBfile1
'Rename text file to .VBS
oShell.run "CMD /C rename " & VBfile & ".txt " & VBfile1 , 0, true
end sub