Automate Setting Allow Agent to Act as Proxy on SCOM Agents

Hi, Mark Manty Premier Field Engineer for Microsoft here.

Many customers want an automated way to enable agents to act as proxy. Many use PowerShell scripts to perform this on a daily or weekly basis.

Kevin Holman has an excellent example of how to perform this with a PowerShell script: http://blogs.technet.com/b/kevinholman/archive/2010/11/09/how-to-set-agent-proxy-enabled-for-all-agents.aspx?Redirected=true

However, some enterprise customers may have rules in place that prevent you from running PowerShell scripts that are unsigned. While you can sign your PowerShell scripts, it can be time consuming: http://technet.microsoft.com/en-us/magazine/2008.04.powershell.aspx

This example could be scheduled to run to ensure your agents are set to allow agents to run as proxy without having to dig through your agent list or alerts to find out what agents may require this.

Let’s go.

This sample program takes one parameter:

• RMS Server name, example MyRMSServer  

I ran this in a test environment and it does not have to run on a RMS or MS to work. It must meet the below requirements in order to run successfully:

• .NET 3.5 Framework

• SCOM R2 Console (User Interface installed)

• Run as account that has administrative rights to the SCOM Management Group

Download the ZIP file SetAgentProxyEnabled.zip and extract SetAgentProxyEnabled.exe to a folder.

Open an administrative command prompt running under an account that has SCOM administrative privileges.

Change to the directory where you extracted SetAgentProxyEnabled.exe.

Run program “SetAgentProxyEnabled.exe MyRMSServer” where MyRMSServer is your RMS server name and press enter to run.

Program will list all agents that it updated and return count of updated agents. This program will also update any Management servers should they not have Proxy enabled.   Below is an example of running the tool.   Note that the server is not set to allow this agent to act as proxy.

Run the tool to update.

Now my agent has been updated to act as proxy.

Disclaimer: This example is provided “AS IS” with no warranty expressed or implied. Run at your own risk. The opinions and views expressed in this blog are those of the author and do not necessarily state or reflect those of Microsoft.

PowerShell cmdlet Get Unhealthy Agents in SCOM

In customer environments where resources are strained and agent health may have degraded over time this PowerShell cmdlet could help identify the agents in your environment that are currently not functioning. This sample cmdlet can verify if unavailable agents are responding to ping and also remotely check if the HealthService is installed, running and whether it is disabled or set to automatic startup. It also remotely gets the last five or six event log errors from the OpsMgr Event log to help with diagnosing agent issues.

Cmdlet gets all agents that are reporting to the specified Management Group (RMS Server) and returns systems that are “Unavailable” and not in maintenance mode. A System in maintenance mode returns unavailable as it is not currently monitoring, so we exclude those systems from the list returned.

This sample cmdlet takes two parameters:

• First parameter is the RMS Server name, example MyRMSServer

• Second parameter is YES or NO, where YES will perform the remote checking via ping and WMI query to get the state of the HealthService. NO will only return the system names

Below are the instructions on how to install this sample cmdlet on Windows Server 2008 R2 64 bit.

I ran this in a test environment and it does not have to run on a RMS or MS to work. It must meet the below requirements in order to run successfully:

• .NET 4.0 Framework

• PowerShell

• SCOM R2 Console (User Interface installed)

• Run as account that has administrative rights to the SCOM Management Group

• When using “YES” for second parameter: Run as account that has admin rights to systems remotely checking HealthService state OR will not return data for HealthService state

Download the ZIP file that contains PowerShell cmdlet dll file and xml help file (GetUnhealthySCOMAgent.dll and UnhealthyAgentCheck.dll-Help.xml) and save to c:\cmdlets.

PowerShell can read from Powershell.exe.config file that adjusts settings PowerShell uses. If the Powershell.exe.config file does not exist in C:\WINDOWS\system32\WindowsPowerShell\v1.0 then create a Powershell.exe.config file in that directory. If the file exists verify that it is similar to below if required add supportedRuntime v4 line to ensure the cmdlet built on v4 of .NET will work.

Copy the contents below into the config file and save:

<?xml version=”1.0″?/> <configuration><startup useLegacyV2RuntimeActivationPolicy=”true><supportedRuntime version=”v4.0.30319″ /> <supportedRuntime version=”v2.0.50727″/> </startup> </configuration>

Open PowerShell and Run as administrator.

Run commands below:

set-alias installutil $env:windir\Microsoft.Net\Framework64\v4.0.30319\installutil

cd c:\cmdlets

installutil .\GetUnhealthySCOMAgent.dll

get-Pssnapin -registered

Verify the cmdlet is displayed in the registered list.

add-pssnapin GetUnhealthySCOMAgentPSSnapin

Get-UnhealthyAgent MMSCOMRMS NO

It is likely that your list is larger than mine, so you may want to pipe results to some file and then copy the contents to excel.

Strings are tab delimited so it will format nicely with a paste into Excel.

Get-UnhealthyAgent MMSCOMRMS YES | out-file c:\cmdlets\output.txt

Then you can open the file and copy and paste to Excel.

NOTE: This is the command line to use if you want to uninstall the cmdlet:

installutil /u .\GetUnhealthySCOMAgent.dll

Cmdlets can help automate many tasks to reduce workload and improve your environments health. Let me know what you think.

Disclaimer: This example is provided “AS IS” with no warranty expressed or implied. Run at your own risk. The opinions and views expressed in this blog are those of the author and do not necessarily state or reflect those of Microsoft.

Automate Sealing SCOM Management Packs

Sealing Management Packs in SCOM requires that you manually type in several paths into the commands you run. If you want to save previous versions this would cause additional changes to command line or manually copying prior versions before sealing again.

Here is a technet article on sealing Management Packs. 

This is a sample of how one may automate the sealing process to reduce errors and retain version folders for history.

Lets get started.

Create a folder named MPStore and copy MPSeal.exe and sn.exe to that folder.

Create a folder named MP in the MPStore folder and copy all referenced Management packs to this directory.

Create a file names sealMP.cmd in the MPStore folder and copy the contents below into the file and save.

Change /Company “Your Company”  with your company name in quotes.

set var=0

set var1=1

:versioncheck

set /a var =%var%+%var1%

if EXIST %1\V%var% goto versioncheck

if %var% GTR %var1% goto sealmp

REM Make new directories

md c:\MPStore\%1\V1

md c:\MPStore\%1\V1\key

sn -k c:\MPStore\%1\V1\key\PairKey.snk

sn -p c:\MPStore\%1\V1\key\PairKey.snk c:\MPStore\%1\V1\key\PubKey

sn -tp c:\MPStore\%1\V1\key\PubKey

:sealmp

REM V1 Existed so do not run sn.exe REM make new directories

md c:\MPStore\%1\V%var%

md c:\MPStore\%1\V%var%\input

md c:\MPStore\%1\V%var%\output

REM gets first xml file in app folder root.

for /F “delims=” %%a in (‘dir /b “c:\MPStore\%1\*.xml”‘) do set varfile=%%a

move c:\MPStore\%1\%varfile% c:\MPStore\%1\V%var%\input

mpseal c:\MPStore\%1\V%var%\input\%varfile% /I “c:\MPStore\MP” /Keyfile “c:\MPStore\%1\V1\key\PairKey.snk” /Company “Your Company” /Outdir “c:\MPStore\%1\V%var%\output”

:ending

REM verify output MP file was created in output directory for new version.

You should have folders that resemble this:

Now you are ready to seal your Management Packs.

Create a folder with your application name (Example: MyWebApp) and copy your unsealed Management pack to this new folder.

Open a command prompt (run as administrator – elevated).

Change to the MPStore directory and run sealmp.cmd MyWebApp.

This will create your key by running sn.exe and will seal the FIRST xml file if finds in the MyWebApp folder.

• ·         Unsealed MP will be moved to the V1\input folder

. • ·         Key will be stored in V1\key folder.

• ·         Sealed MP will be created in V1\output folder.

When you need to modify that MP simply copy your unsealed MP from the V1\input folder to a working folder where you can modify and then increment the MP version. Copy the updated unsealed MP to the MPStore\MyWebApp folder and run sealmp.cmd MyWebApp.

Note the following:

• ·         Unsealed MP will be moved to the V2\input folder.

• ·         Key will be used from the V1\key folder. Uses original key from first run for each subsequent seal.

• ·         Sealed MP will be created in V2\output folder.

Now you have one location that will contain all of your custom Management packs along with version folders for history of each management pack sealed.

I would recommend backing up your MPStore folder to ensure you can recover your custom Management packs should the need arise.

Registry tweaks for SCOM measure twice cut once

Hi all,

Wanted to call out something that happened recently with a customer. When modifying registry ensure that you double or triple check any changes made: Registry Tweaks  (note Kevin’s useful and handy reg add commands – that helps prevent below issue from occurring in first place). A customer had inadvertently added the dalinitiateclearpool new qword (instead of dword) and then the sdk service would not stay running.

Here are the errors you may see on your management server with incorrect keys created. 26399 and 29380 Scroll down and note in the 29380 event log description we see:

“DataAccessRegistry.ReadInitiateClearPool” tipping us off on the issue. Simply delete the qword value and create new dword value and then the sdk service runs as designed.

Log Name:      Operations Manager Source:        OpsMgr SDK Service Date:          2/5/2013 1:06:23 PM Event ID:      26339 Task Category: None Level:         Error Keywords:      Classic User:          N/A Description: An exception was thrown while initializing the service container. Exception message: Initialize Full exception: Feature of type From Log Name:      Operations Manager Source:        OpsMgr SDK Service Date:          2/13/2017 14:25:27 Event ID:      26380 Task Category: None Level:         Error Keywords:      Classic User:          N/A Description: The System Center Data Access service failed due to an unhandled exception. The service will attempt to restart. Exception: Microsoft.EnterpriseManagement.ConfigurationReaderException: The feature named ‘OperationsManager’ and of type ‘Microsoft.EnterpriseManagement.ServiceDataLayer.IDataAccessFeature, Microsoft.EnterpriseManagement.DataAccessService.Core, Version=7.0.5000.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35’ cannot be added to the container. —> Microsoft.EnterpriseManagement.ComponentActivationException: The constructor for the component threw an exception. Please see the inner exception for more details. —> System.TypeInitializationException: The type initializer for ‘Microsoft.EnterpriseManagement.DataAccessLayer.DataAccessRegistry’ threw an exception. —> System.TypeInitializationException: The type initializer for ‘Microsoft.EnterpriseManagement.DataAccessLayer.GlobalDefaults’ threw an exception. —> System.InvalidCastException: Specified cast is not valid. at Microsoft.EnterpriseManagement.DataAccessLayer.DataAccessRegistry.ReadInitiateClearPool(String product) at Microsoft.EnterpriseManagement.DataAccessLayer.GlobalDefaults.Initialize(String product) at Microsoft.EnterpriseManagement.DataAccessLayer.GlobalDefaults..cctor() — End of inner exception stack trace — at Microsoft.EnterpriseManagement.DataAccessLayer.DataAccessRegistry.InitializeStateMap() at Microsoft.EnterpriseManagement.DataAccessLayer.DataAccessRegistry..cctor() — End of inner exception stack trace — at Microsoft.EnterpriseManagement.DataAccessLayer.DataAccessRegistry.StateMap(String product) at Microsoft.EnterpriseManagement.DataAccessLayer.RetryPolicy..ctor() at Microsoft.EnterpriseManagement.ServiceDataLayer.DataAccessFeatureImplementation..ctor() at Microsoft.EnterpriseManagement.ServiceDataLayer.DataAccessFeatureImplementation..ctor(EnterpriseManagementObjectViewName objectView) — End of inner exception stack trace — at Microsoft.EnterpriseManagement.ComponentActivator.Activate[T](ActivationContext`1 context) at Microsoft.EnterpriseManagement.SingletonLifetimeManager`1.GetComponent[K]() at Microsoft.EnterpriseManagement.FeatureContainer.GetFeatureInternal[T](Type type, String featureName) at Microsoft.EnterpriseManagement.FeatureContainer.AddFeatureInternal[T,V](ActivationContext`1 context, String featureName) — End of inner exception stack trace — at Microsoft.EnterpriseManagement.ConfigurationReaderHelper.ReadFeatures(XPathNavigator navi, IContainer container) at Microsoft.EnterpriseManagement.ConfigurationReaderHelper.Process() at Microsoft.EnterpriseManagement.ServiceDataLayer.DispatcherService.Initialize(InProcEnterpriseManagementConnectionSettings configuration) at Microsoft.EnterpriseManagement.ServiceDataLayer.DispatcherService.InitializeRunner(Object state) at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) at System.Threading.ThreadHelper.ThreadStart(Object obj) Event Xml: < Event xmlns=”http://schemas.microsoft.com/win/2004/08/events/event”> < System> < Provider Name=”OpsMgr SDK Service” /> < EventID Qualifiers=”49152″>26380 < Level>2 < Task>0 < Keywords>0x80000000000000 < TimeCreated SystemTime=”2017-02-13T19:25:27.000000000Z” /> < EventRecordID>4783657 < Channel>Operations Manager < Computer>MyComputer.failure.com < Security /> < /System> < EventData> < Data>Microsoft.EnterpriseManagement.ConfigurationReaderException: The feature named ‘OperationsManager’ and of type ‘Microsoft.EnterpriseManagement.ServiceDataLayer.IDataAccessFeature, Microsoft.EnterpriseManagement.DataAccessService.Core, Version=7.0.5000.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35’ cannot be added to the container. —> Microsoft.EnterpriseManagement.ComponentActivationException: The constructor for the component threw an exception. Please see the inner exception for more details. —> System.TypeInitializationException: The type initializer for ‘Microsoft.EnterpriseManagement.DataAccessLayer.DataAccessRegistry’ threw an exception. —> System.TypeInitializationException: The type initializer for ‘Microsoft.EnterpriseManagement.DataAccessLayer.GlobalDefaults’ threw an exception. —> System.InvalidCastException: Specified cast is not valid. at Microsoft.EnterpriseManagement.DataAccessLayer.DataAccessRegistry.ReadInitiateClearPool(String product) at Microsoft.EnterpriseManagement.DataAccessLayer.GlobalDefaults.Initialize(String product) at Microsoft.EnterpriseManagement.DataAccessLayer.GlobalDefaults..cctor() — End of inner exception stack trace — at Microsoft.EnterpriseManagement.DataAccessLayer.DataAccessRegistry.InitializeStateMap() at Microsoft.EnterpriseManagement.DataAccessLayer.DataAccessRegistry..cctor() — End of inner exception stack trace — at Microsoft.EnterpriseManagement.DataAccessLayer.DataAccessRegistry.StateMap(String product) at Microsoft.EnterpriseManagement.DataAccessLayer.RetryPolicy..ctor() at Microsoft.EnterpriseManagement.ServiceDataLayer.DataAccessFeatureImplementation..ctor() at Microsoft.EnterpriseManagement.ServiceDataLayer.DataAccessFeatureImplementation..ctor(EnterpriseManagementObjectViewName objectView) — End of inner exception stack trace — at Microsoft.EnterpriseManagement.ComponentActivator.Activate[T](ActivationContext`1 context) at Microsoft.EnterpriseManagement.SingletonLifetimeManager`1.GetComponent[K]() at Microsoft.EnterpriseManagement.FeatureContainer.GetFeatureInternal[T](Type type, String featureName) at Microsoft.EnterpriseManagement.FeatureContainer.AddFeatureInternal[T,V](ActivationContext`1 context, String featureName) — End of inner exception stack trace — at Microsoft.EnterpriseManagement.ConfigurationReaderHelper.ReadFeatures(XPathNavigator navi, IContainer container) at Microsoft.EnterpriseManagement.ConfigurationReaderHelper.Process() at Microsoft.EnterpriseManagement.ServiceDataLayer.DispatcherService.Initialize(InProcEnterpriseManagementConnectionSettings configuration) at Microsoft.EnterpriseManagement.ServiceDataLayer.DispatcherService.InitializeRunner(Object state) at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) at System.Threading.ThreadHelper.ThreadStart(Object obj) < /EventData> < /Event>

Monitoring Windows MongoDB with SCOM

Hi, Mark Manty Microsoft PFE providing an example Management pack for monitoring MongoDB on Windows Servers. 

Get the example MP from TechNet gallery. 

This management pack has two monitors configured for monitoring the MongoDB Windows service and monitor and alert when less than 100 connections are available. 

The management pack collects many performance counters from a script that runs ServerStatus query every 15 minutes. If you want to disable or add counters to be collected, you must edit the script data source.

Details on removing (disabling a collection) below:

Open the MP with notepad and cut any lines that you do not want collected.

Move them above where the performance counters that are disabled are located and comment out the lines that you move by putting a single quote ‘ character at the front of the line.

Details on adding performance counter to collect that is returned from ServerStatus:

To add counters cut them from the commented out lines and move them to the variable selection. Then uncomment out the line by removing the single quote ‘ character at front of line. 

Adding threshold monitors for a given counter details below:

With Management pack already installed in your environment, select Authoring and change Scope to MongoDB 4.x Windows Server.

Select Authoring – Management Pack Objects – Monitors and right click create a monitor – Unit Monitor.

Select Scripting – Generic – Timed Script Two State Monitor. Select the MongoDB MP and select Next.

Provide a name for the new unit monitor and select the target of MongoDB 4.x Windows Server and select Next

Select the frequency to run the monitor (default is 15minutes) and select Next.

Copy script below and paste into next screen for script.

Note at end of script if you want to change <= to >= based on the way you want your threshold check to be less than or greater than the value passed to the script.

‘ SCRIPT NAME: MongoDBServerStatusCheckValue.vbs

‘ PARAMETERS: 10 “asserts.rollovers”

‘   Where 10 is the Threshold to check counter value

‘     and “asserts.rollovers” is the counter value to check from custom perf collection

‘ Returns: State = “Good” or “Bad”

‘          SCOM Parameter Name: Property[@Name=’State’]

‘          Unhealthy: Contains “Bad”

‘          Healthy: Contains “Good”

‘          Return = “Custom Message you want to display in the Alert Message”

‘ ALERT MESSAGE: To display in Alert description “Return” value see below example

‘ Message: $Data/Context/Property[@Name=’Return’]$

dim oArgs, sReturn

sReturn = “”

Set oAPI = CreateObject(“MOM.ScriptAPI”)

Set oArgs = WScript.Arguments

‘map event types & numbers to friendly names

Const EVENT_TYPE_ERROR = 1

Const EVENT_TYPE_WARNING = 2

Const EVENT_TYPE_SUCCESS = 4

If oArgs.Count < 2 Then

    ‘ If the script is called without the required arguments, ‘ create an information event and then quit. ‘

    Set objShell = Wscript.CreateObject(“Wscript.Shell”) ‘

    objShell.LogEvent EVENT_TYPE_ERROR, “MongoDBServerStatusCheckValue.vbs run with an incorrect number of arguments.”

    WScript.Quit -1

End If

dim iThreshold, sCounterCheck

‘GetArgs

‘0 is threshold Example (10)

‘1 is countervalue to check Example (“asserts.rollovers”)

iThreshold = CLng(trim(oArgs.Item(0)))

sCounterCheck = trim(oArgs.Item(1))

Set oAPI = CreateObject(“MOM.ScriptAPI”)

Set wshNetwork = WScript.CreateObject( “WScript.Network” )

dim strComputerName,sCommand

strComputerName = wshNetwork.ComputerName

Set objShell = WScript.CreateObject(“WScript.Shell”)

sCommand = “””C:\Program Files\MongoDB\Server\4.0\bin\mongo.exe””” & ” –eval ” & “””db.runCommand( { serverStatus: 1 } ).” & sCounterCheck & “”””

‘Wscript.Echo sCommand

Set objExec = objShell.Exec(sCommand)

    line = objExec.StdOut.ReadLine()

    line = objExec.StdOut.ReadLine()

    line = objExec.StdOut.ReadLine()

    line = objExec.StdOut.ReadLine()

               Wscript.Echo line

               Set oBag = oAPI.CreatePropertyBag()

               if Clng(trim(line)) <= iThreshold then

           sReturn = “MongoDB ServerStatus Value for ” & sCounterCheck & ”  was equal to or exceeded threhsold of ” & iThreshold & “. Current value checked was ” & line & “. Command run to get value: ” & sCommand

                  ‘add data to propertybag and add item

           Call oBag.AddValue(“Value”,line)

                  Call oBag.AddValue(“State”,”Bad”)

                  Call oBag.AddValue(“Return”,sReturn)

                  Call oAPI.AddItem(oBag)

               else

                  ‘add data to propertybag and add item

           Call oBag.AddValue(“Value”,line)

                  Call oBag.AddValue(“State”,”Good”)

                  Call oBag.AddValue(“Return”,”Within Threshold Limit”)

                  Call oAPI.AddItem(oBag)

               end if

‘Return all property bags.

oAPI.ReturnItems()

Provide a file name with .vbs extension. Change timeout to 5 minutes.

Use this for parameters: 100 “connections.available”

For your case you would put threshold value as first parameter and then the counter name that you would like to check value of for alerting.

NOTE: Double check is this is correct.

Run script manually to validate that your parameters work asexpected.


Paste in below to check for Good and Bad returned State property bag value for the monitors Unhealthy and Healthy expression checks.

Property[@Name=’State’]

Select warning or critical for unhealthy condition of thenew monitor you are creating.

Paste below string into Alert description to allow for script data to be entered into your alert description.

$Data/Context/Property[@Name=’Return’]$

Select values to generate alert and auto resolve alert monitor. Select priority and severity you would like for the alert.

Select Create to create your new script monitor.

See new monitor created and validate it is targeted to MongoDB target.

MONGODB views in management pack.

MongoDB Monitoring folder contains three views. One for Alerts, performance and discovered MongoDB Servers.

Performance data collected will display similar to below. Select items to see the data collected.

Reporting example on how to configure performance report to display historical data for MongoDB performance counters collected.