SCOM Management Pack Comparison Organization Chart Made Easy with Powershell

Keeping your management packs in sync across management groups can be a challenge. Here’s an easy way to create a comparison chart/report with PowerShell.

Export MP data from each management group

Connect to the SDK of the targeted management group and run the snippet below.

# Export MPs as generic XML objects into .xml file. 
# Note, these are not "management pack" files.
$OutputFolder = 'C:\Temp\MPData' #Set this to your needs
New-Item -Path $OutputFolder -ItemType Directory -ErrorAction SilentlyContinue
$MGName = (Get-SCOMManagementGroup).Name
Get-SCOMManagementPack | Export-Clixml -Path (Join-Path $OutputFolder "$($MGName).xml") -Verbose
MP data is stored in .xml file named the same as the management group, “SCOMLAB”.

Run the above script for EACH management group. Put all exported .xml files into your working directory. In the example below you can see two files from two different management groups.

Generate comparison list

Specify your working directory.
Set $IncludeMPVersion to include/exclude the MP version columns

Note: There is no script file to download. Just copy/paste the snippets into your preferred PowerShell console.

# Configure as needed
# Directory that contains exported MP .XML object files

$InputDirectory = 'C:\Temp\MPData'
# Output File Name
$OutputFileName = 'MPVersionList.csv'
$IncludeMPVersion = $false # Set $true to include MP Sealed statuses

$hashAllMPsbyGroup = @{}
$hashAllMPs = @{}
ForEach ($MPFilePath in ((Get-ChildItem $InputDirectory -Filter "*.xml").FullName )) {
  $hashTempMPs = @{}
  # Create a hash table with all known MPs. Key=MPName, Value=MPObject
  [array]$MPs = (Import-Clixml -Path $MPFilePath)
  ForEach ($MP in $MPs){
    Try {
      # Only unique MPs (Names) will be added
    } Catch {
      # Collisions are expected as all mgmt groups will likely have the same common/core MP Names
    Try {
      # Hash to contain all MPs for the mgmt group
    } Catch {
      Write-Host "Problem adding $($MP.Name) to `$hashTempMPs ! Error: $($_ | Out-String)" -F Red
  # Add to hash table: Key=MgmtGroup name, Value=Hash table of all MP objects from the specific mgmt group (Key=MPName, Value=MPobject)
  $hashAllMPsbyGroup.Add(((Split-Path $MPFilePath -Leaf) -replace '.xml' ),$hashTempMPs)

[System.Collections.ArrayList]$array = @{}
# Iterate through all known MPs to construct master list of names and versions
ForEach ($MPNameKey in ([array]($hashAllMPs.Keys)) ) {
  $obj = New-Object -TypeName PSCUSTOMOBJECT
  $obj | Add-Member -MemberType NoteProperty -Name 'MPName' -Value "$($hashAllMPs[$MPNameKey].Name)"
  $obj | Add-Member -MemberType NoteProperty -Name 'MPDisplayName' -Value "$($hashAllMPs[$MPNameKey].DisplayName)"
  ForEach ($MGroup in ([array]$hashAllMPsbyGroup.Keys)) {
    Try {
      $tmpVersion = (($hashAllMPsbyGroup[$MGroup]."$($MPNameKey)").Version.ToString())
    } Catch {
      # MP object (hash Key) may not exist which is fine.
      $tmpVersion = ''
    $obj | Add-Member -MemberType NoteProperty -Name "$($MGroup)" -Value $tmpVersion
    If ($IncludeMPVersion) {
      $obj | Add-Member -MemberType NoteProperty -Name "IsSealed($($MGroup))" -Value (($hashAllMPsbyGroup[$MGroup]."$($MPNameKey)").Sealed)
  $Null = $array.Add($obj)
$array | Sort-Object -Property MPName | Export-Csv -NoTypeInformation -Path (Join-Path $InputDirectory $OutputFileName) -Encoding UTF8 -Force -Verbose


Leave a Reply

Your email address will not be published. Required fields are marked *