USE AT YOUR OWN RISK! I WILL NOT TAKE RESPONSIBILITY FOR ANY DAMAGE THIS SCRIPT CAUSES!
The attached Script takes 3 Arguments
- RMS (FQDN of your Root Management Server)
- MPName (some MPs Full Name like Microsoft.Windows.Library)
- MPPartialName (which is useful if you want to get rid of like all MPs with some Prefix like your company name)
In case the MPName was provided it will get the Management Pack and in case it was found it will prompt you if you want to uninstall it.
If you choose yes it will calculate it's Dependencies and will prompt you again if you want to delete the Management Pack including it's dependant Management Pack.
If you choose yes, it will uninstall all dependant Management Packs, and afterwards the initial one.
In case the MPPartialName was provided it will query for all Management Packs that match the provided String. It will then run the same Process as it does with the MPName for all found Management Packs.
Find the Script as well as Dummy Management Packs with Dependencies in the attached Zip File.

Code:
# Author: Andreas Zuckerhut
# This Script will take either a full Management Pack Name or a Partial Name.
# It will then prompt you for Uninstallation. If you choose Yes, it will calculate it's Dependencies and output them.
# Once finished it will prompt you again if you want to uninstall the MP including it's dependant MPs.
#Parameters:
#Param1 - RMS = The FQDN of the Root Management Server
#Param2 - MPName = The full MPName, only one MP can be found and deleted (including the referencing MPs
#Param3 - MPPartialName = A part of an MPName, therefore we run a Match-Query and delete all MPs that were found including the referencing ones.
#Param4 - Balls of Steel Mode: In this Mode, it will answer all Questions with Yes automatically.
#Example: MPName: MPUninstall.ps1 "rms.code4ward.net" "MyCustom.ManagementPack" ""
#Example: MPPartialName: MPUninstall.ps "rms.code4ward.net" "" "MyCustom"
param([string]$rms,[string]$mpName,[string]$mpPartialName,[string]$ballsOfSteel)
function Main()
{
if ($ballsOfSteel -ne "true"){$ballsOfSteel = [bool]$false}else{$ballsOfSteel = [bool]$true}
Write-Host "-----------------------------"
Write-Host "Received Arguments:`r`nRMS = $rms,`r`nMPName = $mpName,`r`nMPPartialName = $mpPartialName,`r`nBalls of Steel Mode: $ballsOfSteel"
Write-Host "-----------------------------"
if (Check-Parameters)
{
# Load the Operations Manager Environment
Load-OperationsManagerEnvironment($rms)
# Query for all Management Packs that are currently installed in your Management Group
# We need that list for the calculation of the Dependencies.
$Script:MPFullQuery = get-managementpack
Write-Host "--------------------------------------------"
if ($mpName.Length -gt 0)
{
# Get the Management Pack with the MPName that was provided.
$MP = get-managementpack | ?{$_.Name -eq $mpName}
$MPName = $MP.name
# Output the MP that was found.
if ($MP -eq $null)
{
Write-Host "Management Pack with ID $CurrentMPName was not found."
}
else
{
Write-Host "Management Pack $MPName was found."
Write-Host "Preparing Uninstallation."
}
# Call the Preparation function. It holds the Main Logic for the Uninstallation.
Prepare-Uninstallation $MPName
}
if ($mpPartialName.Length -gt 0)
{
# Get all Management Packs that match the PartialName that was provided.
$MPQueryResult = get-managementpack | ?{$_.Name -match $mpPartialName}
# Output all Management Packs that were found.
Write-Host "The following Management Packs were found. You have to approve each uninstallation:"
foreach ($MP in $MPQueryResult)
{
Write-Host $MP.Name
}
Write-Host "-----------------------------"
# Prepare the Uninstallation for each Management Pack in the List.
foreach ($MP in $MPQueryResult)
{
Prepare-Uninstallation $MP.Name
}
}
}
}
function Prepare-Uninstallation([string]$mpName)
{
# Create a new Table for the Management Packs that will get deleted.
Create-MPUninstallTable
# Prompt the User for a decision if he wants to uninstall the MP or not.
if ((Check-UserVerified "Are you sure that you want to delete the MP [$mpName]?"))
{
# In case the User verified that the MP can be deleted, output that.
Write-Host "You verified that MP $mpName can be deleted. Calculating Dependencies..."
Write-Host "--------------------------------------------"
Write-Host $mpName
# Add the MP to the MPUninstall Table
Add-MPToMPUninstallTable $mpName 0
# Get the referencing MPs of the MP.
Get-MPReferences $mpName 0
# Prompt the User again if he really wants to delete the MP including all dependant MPs
Write-Host "--------------------------------------------"
Write-Host "In order to delete MP $mpName, all dependant Management Packs have to be deleted as well."
Write-Host "Please check the Dependencies above."
if ((Check-UserVerified "Are you sure that you want to delete the MP $MPName as well as all dependant MPs?"))
{
# In case the User verified that the MP can be deleted, output that and begin the Uninstall Process.
Write-Host "--------------------------------------------"
Remove-MPIncludingReferencingMPs
}
else
{
# In case the user chose No, we skip the Uninstallation.
Write-Host "You decided that MP $mpName is not to be deleted. Skipping Uninstallation."
Write-Host "--------------------------------------------"
}
}
else
{
# In case the user chose No, we skip the Uninstallation.
Write-Host "You decided that MP $mpName is not to be deleted. Skipping Uninstallation."
Write-Host "--------------------------------------------"
}
}
function Remove-MPIncludingReferencingMPs
{
# We sort the Datatable by the Level so we can then uninstall the Management Packs in the right order.
[System.Data.DataView]$View = $Script:MPUninstallTable.DefaultView
$View.Sort = "Level DESC"
$Script:MPUninstallTable = $View.ToTable()
foreach ($Row in $Script:MPUninstallTable.Rows)
{
# Each Row holds a Management Pack Name.
$MPName = ($Row["MPName"])
trap{continue}
# We get each Management Pack
$MP = Get-ManagementPack -Name $MPName
$Error.Clear()
if ($MP -eq $null)
{
# If the MP wasn't found, we skip the uninstallation of it.
Write-Host "$MPName has already been uninstalled"
}
else
{
# In case it was still there we uninstall it.
Write-Host "Uninstalling $MPName"
Uninstall-ManagementPack $MP
}
}
# Output that the script is finished.
Write-Host "-----------------------------"
Write-Host "Finished. All your Management Packs are belong to null"
}
function Get-MPReferences([string]$mpName,[int]$level)
{
# Create a Collection for all Referencing MP Names
$ReferencingMPNames = New-Object System.Collections.ArrayList
# For each Level we create a new Prefix for the Dependency Output.
# Basically, per Level we need to add some Spacing.
$CurrentLevel = 0
[string]$Prefix = "+---"
while ($CurrentLevel -lt $level)
{
$Prefix = "| " + $Prefix
$CurrentLevel = $CurrentLevel + 1
}
# Raise the Level by one.
$level = $level + 1
# We check each MP in the Management Group if it refers to our MP
foreach ($MPToCheck in $Script:MPFullQuery)
{
foreach ($Reference in $MPToCheck.References)
{
if ($Reference.Name -eq $mpName)
{
# In case one was found we add it to the Table
Add-MPToMPUninstallTable $MPToCheck.Name $level | Out-Null
# Additionally we add it to the current MPs List
$ReferencingMPNames.Add($MPToCheck.Name) | Out-Null
}
}
}
# We check all the Dependencies of the current MP
foreach ($ReferencingMPName in $ReferencingMPNames)
{
#Output the Dependencies
Write-Host "$Prefix$ReferencingMPName"
# Afterwards we check this MPs Dependencies.
Get-MPReferences $ReferencingMPName $level
}
}
function Check-UserVerified($message)
{
# In case Balls of Steel mode is true, we skip the Questions.
if ($ballsofSteel)
{
return $true
}
else
{
# If user chooses Yes we return true, else we return false.
$No = new-Object System.Management.Automation.Host.ChoiceDescription "&No",""
$Yes = new-Object System.Management.Automation.Host.ChoiceDescription "&Yes",""
$Choices = [System.Management.Automation.Host.ChoiceDescription[]]($No,$Yes)
$Caption = "User Input required..."
$Result = $Host.ui.PromptForChoice($Caption,$message,$Choices,0)
if($result -eq 0)
{
return $false
}
if($result -eq 1)
{
return $true
}
}
}
function Create-MPUninstallTable
{
# Create MPUninstall Table
# This Table has a list of Management Packs and holds their Level as well.
[System.Data.DataTable]$Script:MPUninstallTable = New-Object System.Data.DataTable "AlertTable"
$Script:MPUninstallTable.Columns.Add((New-Object System.Data.DataColumn MPName,([string])))
$Script:MPUninstallTable.Columns.Add((New-Object System.Data.DataColumn Level,([int])))
}
function Add-MPToMPUninstallTable([string]$mpName,[int]$level)
{
# This function adds a new Row in the Table.
$NewRow = $Script:MPUninstallTable.NewRow()
$NewRow.MPName = $mpName
$NewRow.Level = $level
$Script:MPUninstallTable.Rows.Add($NewRow)
}
function Check-Parameters
{
# Verify that all needed Parameters were provided.
if ($rms.Length -eq 0 )
{
Write-Host "The Root Management Server Parameter was not provided."
return $false
}
if ($mpName.Length -eq 0)
{
if ($mpPartialName.Length -eq 0)
{
Write-Host "Whether the MP Name nor the MP Partial Name was provided."
Write-Host "Example: MPPartialName: MPUninstall.ps `"rms.code4ward.net`" `"`" `"MyCustom`""
Write-Host "Example: MPName: MPUninstall.ps `"rms.code4ward.net`" `"MyCustom.ManagementPack.For.Something.Awesome`" `"`""
return $false
}
else
{
return $true
}
}
else
{
return $true
}
}
function Load-OperationsManagerEnvironment([string]$rms)
{
#Check if PSSnapin is already loaded, if not, load it.
if ((Get-PSSnapin | Where-Object {$_.Name -eq 'Microsoft.EnterpriseManagement.OperationsManager.Client'}) -eq $null)
{
Write-Host("Loading Operations Manager PS Snapin")
Add-PSSnapin Microsoft.EnterpriseManagement.OperationsManager.Client
}
else
{
Write-host("Operations Manager PS Snapin is already loaded")
}
# Load the Assemblies
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.EnterpriseManagement.OperationsManager")
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.EnterpriseManagement.OperationsManager.Common")
# Set Location to the RMS
Write-Host("Setting Location $rms.")
Set-Location "OperationsManagerMonitoring::" -ErrorVariable errSnapin;
$MG = New-ManagementGroupConnection -ConnectionString:$rms -ErrorVariable errSnapin;
$Script:MG = New-Object Microsoft.EnterpriseManagement.ManagementGroup($rms)
Set-Location $rms -ErrorVariable errSnapin;
}
# Call the Main function.
Main