Using the Operations Manager Command Shell against multiple management groups

In our environment we have 5 production management groups (3 for "core" monitoring, 1 for application monitoring and one for connecting to our network monitoring system).  Many times I want to be able to quickly run some cmdlet across all of these management groups to do things like the following:

  • Find a notification subscription in each and disable it if it is enabled
  • Find an agent in one of the management groups and gather some information about it or put it into maintenance mode
  • Import, export or compare management packs

Since I'm also too lazy to be bothered with always having to run the Operations Manager command shell shortcut and then run "New-ManagementGroupConnection" 4 times (I get one connection for free on start-up and have to kick up the others) I decided to add a couple things to my PowerShell profile to simplify this:

  • A hashtable (associative array) named $RMS that contains a list of our root management servers
  • A function named Start-OM that loops through each entry in $RMS and initializes a connection to each with the OpsMgr PowerShell provider

Note: For those that may not be familiar with PowerShell profiles check out the about_profiles topic online or by running "get-help about_profiles | more" within PowerShell.

If you want to do this yourself do the following:

  • Start Windows PowerShell on a system that has the Operations Manager command shell installed, under the credentials that you use to access your management groups

  • Run the following statement which will test to see if you have a profile, create the profile if it does not exist and then open the profile with notepad:

    if (!(test-path $profile)){new-item -type file -path $profile -force}; notepad $profile

  • Add the $RMS variable.  The keys should be easy to remember names for your MGs and the values should be the names of the corresponding RMS for each MG.  The following is an example of what this would look like and will need to be customized for your environment:

    $RMS = @{CORE1='RMS-SRV-01';CORE2='RMS-SRV-02';APP1='RMS-SRV-03';NET1='RMS-SRV-04'}

  • Add the Start-OM function

    function Start-OM
    # Move to the location where the snap-in is located
    cd "$env:ProgramFiles\System Center Operations Manager 2007\"
    # Load the OpsMgr snap-in so we have access to the OpsMgr cmdlets and provider
    Add-PSSnapin Microsoft.EnterpriseManagement.OperationsManager.Client
    # Load the helper functions provided with the OpsMgr snap-in
    # Loops through each of the values (RMS server names) and establishes a connection
    $RMS.values | %{Start-OperationsManagerClientShell -ManagementServerName: $_ -PersistConnection: $false -Interactive: $false;}
    # Move to the root of the monitoring drive so that you can access the management group connections
    Set-Location Monitoring:\
    # Show the list of all established connections

  • Save the changes to the file

  • Load the profile by either closing PowerShell and openning it again or by running the following command:


  • Run the new function


So now that you've got a PowerShell session setup with active connections multiple management groups, you do the following to run one or more cmdlets or scripts against those connections:

  # Move to the root of the Monitoring:\ PSDrive
cd monitoring:\

  # Use get-childitem to loop through each connection and run a cmdlet against each connection. Pass into the cmdlet the PathName from the connection item
get-childitem | foreach-object{<OPSMGR_CMDLET_NAME> <PARAMETERS> $_.PathName }

The following example will loop through each connection and get the management pack object for "Microsoft.SystemCenter.2007" (aka "System Center Core Monitoring" or the OpsMgr MP):

  get-childitem | foreach-object{Get-ManagementPack -Name Microsoft.SystemCenter.2007 -Path $_.PathName }

I hope that some of you find this as useful as I have and that these tricks save you some time down the road.