As everyone who has worked with System Center Operations Manager or Service Manager know, after a while your custom management packs (MP) can become littered with unneeded references. This can cause MPs to have dependencies on other MPs even if they don’t actually have any interaction with each other. After talking with my colleague Cameron Fuller, we realized that SCOM and SCSM both suffer from this problem. After looking into this problem, I decided to create a PowerShell script that would check all the references in an MP and remove any that are unneeded. Luckily, since SCOM and SCSM both use the same basic management structure, I was able to create one script that can run for both systems.

When you execute the script, it will make a backup of the MP with the current version number appended to the file name. Then it will increment the MP version, then it gets all of the reference aliases, checks thought-out the MP for other references to it. If it does not find any other references to the alias it removes it from the XML. Depending on the size of the number of references the script can take a few seconds to a few minutes to run.

To run the script you need to export your management pack in XML form. It will not work on a sealed management pack. Then you just need to supply the MP path and name as the –file parameter.

Syntax
Clean_MP_References.ps1 -file <XML File and Path>

Example
.\Clean_MP_References.ps1 -file C:\MPs\Custom.Change.Library.xml

image

As the script runs it will output the name of the backup file and the unneeded references that were removed. Once it completes the cleaned and versioned MP file is ready to be reimported.

I have provided a copy of the code below, or if you prefer you can click this Link to download a copy.

Param            

(                      

    [Parameter(Mandatory=$true)]           

    $file

)

 

$xml = [xml] (Get-Content $file)

$ver = $xml.ManagementPack.Manifest.Identity.Version

 

Write-Host "nStarting Clean Up Process......"

 

Function IncrementVersion($file,$ver)

{

    $lines = (Get-Content $file)

    $inc = $ver.Substring($ver.LastIndexOf(".")+1,$ver.Length-($ver.LastIndexOf(".")+1))

    $inc = [int]$inc+1

    $inc = $ver.Substring(0,$ver.LastIndexOf(".")+1)+[string]$inc

    $j = 0

    $c = 0

    Foreach($line in $lines)

    {

        $c ++

        If($c -eq 1){$line | out-file $file

        }

        Else{

            If($line.Contains('<Identity>')){$j = 1}

            If($j -eq 1)

            {

                $line -replace("<Version>$ver</Version>","<Version>$inc</Version>") | out-file $file -append

            }

            Else{$line | out-file $file -append}

            If($j -eq 1){If($line.Contains('</Identity>')){$j = 0}}

        }

    }

}

 

Function RemoveReference($Ref,$file)

{

    Write-Host "Removing reference to - $Ref"

    $lines = (Get-Content $file)

    $j = 0

    $c = 0

    Foreach($line in $lines)

    {

        $c ++

        If($c -eq 1){$line | out-file $file}

        Else{

            $man = '<Reference Alias="'+ $Ref +'">'

            If($line.Contains($man)){$j = 1}

            If($j -eq 0)

            {

                $line | out-file $file -append

            }

            If($j -eq 1){If($line.Contains("</Reference>")){$j = 0}}

        }

    }

}

 

# Get References

$xml = [xml] (Get-Content $file)

$Refs = $xml.ManagementPack.Manifest.References.Reference.Alias

 

# Set output array

$badRef = @()

 

# Find Bad References

Foreach($Ref in $Refs)

{

    $i = 0

    $chck = $Ref + "!"

    $lines = Get-Content $file

    Foreach($line in $lines)

    {

        If($line.Contains($chck)){$i ++}

    }

    If($i -eq 0){$badRef += $Ref}

}

 

 

# Confirm if bad references exist

If($badRef.Count -gt 0)

{

    # Backup Orginal

    $ofile = $file -replace(".xml$","-$ver.xml")

    Copy-Item $file $ofile

    Write-Host "nA backup of your file has been created: $ofile n"

    IncrementVersion $file $ver

    Foreach($Ref in $badRef)

    {

        RemoveReference $Ref $file

    }

    Write-Host "nThe clean up is complete.n"

}Else

{

    Write-Host "nNo bad references were found in: $file `n"

}