OpsMgr 2012 Self Maintenance Remove Obsolete Management Packs References Write Action

OpsMgr.2012.Self.Maintenance.Remove.Obsolete.MP.References.Write.Action (WriteActionModuleType)

Element properties:

TypeWriteActionModuleType
IsolationAny
AccessibilityInternal
RunAsDefault
InputTypeSystem.BaseData

Member Modules:

ID Module Type TypeId RunAs 
PSScript WriteAction Microsoft.Windows.PowerShellWriteAction Default

Overrideable Parameters:

IDParameterTypeSelector
BackupBeforeModifybool$Config/BackupBeforeModify$
BackupLocationstring$Config/BackupLocation$
IncrementVersionbool$Config/IncrementVersion$
DetectOnlybool$Config/DetectOnly$
CommonMP1string$Config/CommonMP1$
CommonMP2string$Config/CommonMP2$
CommonMP3string$Config/CommonMP3$
CommonMP4string$Config/CommonMP4$
CommonMP5string$Config/CommonMP5$
TimeoutSecondsint$Config/TimeoutSeconds$

Source Code:

<WriteActionModuleType ID="OpsMgr.2012.Self.Maintenance.Remove.Obsolete.MP.References.Write.Action" Accessibility="Internal" Batching="false">
<Configuration>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" minOccurs="0" name="BackupBeforeModify" type="xsd:boolean"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" minOccurs="0" name="BackupLocation" type="xsd:string"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" minOccurs="0" name="IncrementVersion" type="xsd:boolean"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" minOccurs="0" name="DetectOnly" type="xsd:boolean"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" minOccurs="0" name="CommonMP1" type="xsd:string"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" minOccurs="0" name="CommonMP2" type="xsd:string"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" minOccurs="0" name="CommonMP3" type="xsd:string"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" minOccurs="0" name="CommonMP4" type="xsd:string"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" minOccurs="0" name="CommonMP5" type="xsd:string"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" minOccurs="1" name="TimeoutSeconds" type="xsd:integer"/>
</Configuration>
<OverrideableParameters>
<OverrideableParameter ID="BackupBeforeModify" Selector="$Config/BackupBeforeModify$" ParameterType="bool"/>
<OverrideableParameter ID="BackupLocation" Selector="$Config/BackupLocation$" ParameterType="string"/>
<OverrideableParameter ID="IncrementVersion" Selector="$Config/IncrementVersion$" ParameterType="bool"/>
<OverrideableParameter ID="DetectOnly" Selector="$Config/DetectOnly$" ParameterType="bool"/>
<OverrideableParameter ID="CommonMP1" Selector="$Config/CommonMP1$" ParameterType="string"/>
<OverrideableParameter ID="CommonMP2" Selector="$Config/CommonMP2$" ParameterType="string"/>
<OverrideableParameter ID="CommonMP3" Selector="$Config/CommonMP3$" ParameterType="string"/>
<OverrideableParameter ID="CommonMP4" Selector="$Config/CommonMP4$" ParameterType="string"/>
<OverrideableParameter ID="CommonMP5" Selector="$Config/CommonMP5$" ParameterType="string"/>
<OverrideableParameter ID="TimeoutSeconds" Selector="$Config/TimeoutSeconds$" ParameterType="int"/>
</OverrideableParameters>
<ModuleImplementation Isolation="Any">
<Composite>
<MemberModules>
<WriteAction ID="PSScript" TypeID="Windows!Microsoft.Windows.PowerShellWriteAction">
<ScriptName>RemoveObsoleteMPRefTask.ps1</ScriptName>
<ScriptBody><Script>#==============================================================================
# Script Name: RemoveObsoleteMPRefTask.ps1
# DATE: 12/06/2014
# Version: 1.0
# COMMENT: - Script to clean up obsolete references from unsealed MPs
#==============================================================================
Param (
[Parameter(Mandatory=$false)][String]$BackupBeforeModify,
[Parameter(Mandatory=$false)][string]$BackupLocation,
[Parameter(Mandatory=$false)][String]$IncrementVersion,
[Parameter(Mandatory=$false)][String]$WhatIf,
[Parameter(Mandatory=$false)][string]$CommonMP1,
[Parameter(Mandatory=$false)][string]$CommonMP2,
[Parameter(Mandatory=$false)][string]$CommonMP3,
[Parameter(Mandatory=$false)][string]$CommonMP4,
[Parameter(Mandatory=$false)][string]$CommonMP5
)

#Region FunctionLibs
function Load-SDK()
{
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.EnterpriseManagement.OperationsManager.Common") | Out-Null
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.EnterpriseManagement.OperationsManager") | Out-Null
}

Function Get-ObsoleteReferences ([XML]$MPXML,[System.Collections.ArrayList]$arrCommonMPs)
{
$arrAliasToBeDelete = New-Object System.Collections.ArrayList
$Refs = $MPXML.ManagementPack.Manifest.References.Reference
Foreach ($Ref in $Refs)
{
$RefMPID = $Ref.ID
$Alias = $Ref.Alias
$strRef = "$Alias`!"
If (!($MPXML.Innerxml.contains($strRef)))
{
#The alias is obsolete
#Ignore Common MPs
If (!($arrCommonMPs.contains($RefMPID)))
{
#Referecing MP is not a common MP
[Void]$arrAliasToBeDelete.Add($Alias)
}
}
}
,$arrAliasToBeDelete
}

Function Get-MpXmlString ($MP)
{
$MPStringBuilder = New-Object System.Text.StringBuilder
$MPXmlWriter = New-Object Microsoft.EnterpriseManagement.Configuration.IO.ManagementPackXmlWriter([System.Xml.XmlWriter]::Create($MPStringBuilder))
[Void]$MPXmlWriter.WriteManagementPack($MP)
$MPXML = [XML]$MPStringBuilder.ToString()
$MPXML
}

Function Increase-Version ([String]$CurrentVersion)
{
$vIncrement = $CurrentVersion.Split('.')
$vIncrement[$vIncrement.Length - 1] = ([system.int32]::Parse($vIncrement[$vIncrement.Length - 1]) + 1).ToString()
$NewVersion = ([string]::Join(".", $vIncrement))
$NewVersion
}
#EndRegion

#region Main

#Convert string to boolean
$BackupBeforeModify = [System.Convert]::ToBoolean($BackupBeforeModify)
$IncrementVersion = [System.Convert]::ToBoolean($IncrementVersion)
$WhatIf = [System.Convert]::ToBoolean($WhatIf)

#Define an arraylist to store common MPs
$arrCommonMPs = New-Object System.Collections.ArrayList

[Void]$arrCommonMPs.Add("Microsoft.SystemCenter.Library")
[Void]$arrCommonMPs.Add("Microsoft.Windows.Library")
[Void]$arrCommonMPs.Add("System.Health.Library")
[Void]$arrCommonMPs.Add("System.Library")
[Void]$arrCommonMPs.Add("Microsoft.SystemCenter.DataWarehouse.Internal")
[Void]$arrCommonMPs.Add("Microsoft.SystemCenter.Notifications.Library")
[Void]$arrCommonMPs.Add("Microsoft.SystemCenter.DataWarehouse.Library")
[Void]$arrCommonMPs.Add("Microsoft.SystemCenter.OperationsManager.Library")
[Void]$arrCommonMPs.Add("System.ApplicationLog.Library")
[Void]$arrCommonMPs.Add("Microsoft.SystemCenter.Advisor.Internal")
[Void]$arrCommonMPs.Add("Microsoft.IntelligencePacks.Types")
[Void]$arrCommonMPs.Add("Microsoft.SystemCenter.Visualization.Configuration.Library")
[Void]$arrCommonMPs.Add("Microsoft.SystemCenter.Image.Library")
[Void]$arrCommonMPs.Add("Microsoft.SystemCenter.Visualization.ServiceLevelComponents")
[Void]$arrCommonMPs.Add("Microsoft.SystemCenter.NetworkDevice.Library")
[Void]$arrCommonMPs.Add("Microsoft.SystemCenter.InstanceGroup.Library")
[Void]$arrCommonMPs.Add("Microsoft.Windows.Client.Library")

#Process additional Common MPs passed in via Overrides
$AdditionalCommonMPs = New-Object System.Collections.ArrayList
$CommonMP1,$CommonMP2,$CommonMP3,$CommonMP4,$CommonMP5 | Foreach-Object {If($_.Length -gt 0) {[void]$AdditionalCommonMPs.Add($_)}}

Foreach ($item in $AdditionalCommonMPs)
{
If (!$arrCommonMPs.Contains($item))
{
[Void]$arrCommonMPs.Add($item)
}
}

#Connect to SCOM management group
Load-SDK
$ManagementServer = $env:COMPUTERNAME
Write-Host "Task running from $ManagementServer."
Write-Host "Running Remove Obsolete MP References task on $managementserver`."
#MOMScript API
$oAPI = New-Object -ComObject "MOM.ScriptAPI"
$oAPI.LogScriptEvent("RemoveObsoleteMPRefTask.ps1", 9716, 0, "Running Remove Obsolete MP References task on $managementserver`." )

$MGConnSetting = New-Object Microsoft.EnterpriseManagement.ManagementGroupConnectionSettings($ManagementServer)
$MG = New-Object Microsoft.EnterpriseManagement.ManagementGroup($MGConnSetting)

#Create ManagementPackXMLWriter object if backup is required
If ($BackupBeforeModify -eq $true)
{
If (Test-Path $BackupLocation)
{
$date = Get-Date
$BackupSubDir = "$($date.day)-$($date.month)-$($date.year) $($date.hour)`.$($date.minute)`.$($date.second)"
$BackupDir = Join-Path $BackupLocation $BackupSubDir
} else {
Write-Host "Invalid Backup Location specified."
Exit
}
}

#Get all unsealed MPs
Write-Host "Getting Unsealed management packs..."
$strMPquery = "Sealed = 'false'"
$mpCriteria = New-Object Microsoft.EnterpriseManagement.Configuration.ManagementPackCriteria($strMPquery)
$arrMPs = $MG.GetManagementPacks($mpCriteria)
Write-Host "Total number of unsealed management packs: $($arrMPs.count)"
Write-Host ""
$iTotalUpdated = 0
Foreach ($MP in $arrMPs)
{
Write-Host "Checking MP: '$($MP.Name)'..." -ForegroundColor Green
#Firstly, get the XML
$MPXML = Get-MpXmlString $MP
#Then get obsolete references (if there are any)
$arrRefToDelete = Get-ObsoleteReferences $MPXML $arrCommonMPs

If ($arrRefToDelete.count -gt 0)
{
Write-Host " - Number of obsolete references found: $($arrRefToDelete.count)" -ForegroundColor Yellow
If ($BackupBeforeModify -eq $true)
{
If ($WhatIf -eq $false)
{
#Create Backup Dir if it's not present
if (!(Test-path $BackupDir))
{
New-Item -type directory -Path $BackupDir | Out-Null
}

#Create mpwriter if it's not created
If (!$mpwriter)
{
$mpWriter = new-object Microsoft.EnterpriseManagement.Configuration.IO.ManagementPackXmlWriter($BackupDir)
}

Write-Host " - Backing up $($MP.Name) to $BackupDir before modifying it."
$mpWriter.WriteManagementPack($MP) | Out-Null
} else {
Write-Host " - $($MP.Name) would have been backed up to $BackupDir before modifying it."
}
}
Foreach ($item in $arrRefToDelete)
{
If ($WhatIf -eq $false)
{
Write-Host " - Deleting reference '$item'"
$MP.References.remove($item) | out-Null

} else {
Write-Host " - The reference '$item' would have been deleted."

}
}

#calculate the new version number if $IncrementVersion switch is specified
if ($IncrementVersion -eq $true)
{
$CurrentVersion = $MP.Version.Tostring()
$NewVersion = Increase-Version $CurrentVersion
}

If ($WhatIf -eq $false)
{
If ($IncrementVersion -eq $true)
{
Write-Host " - Updating MP Version from $CurrentVersion to $NewVersion"
$MP.Version = $NewVersion
}

Try
{
$bVerified = $MP.Verify()
}Catch {
$bVerified = $false
}

#accept changes if MP is verified. otherwise reject changes
If ($bVerified -eq $false)
{
Write-Host "MP Verify failed. Reject changes." -ForegroundColor Red
$MP.RejectChanges()
} else {
Write-Host "MP Verified. Accepting changes."
$MP.AcceptChanges()

#Increase total updated count only when changes are accepted.
$iTotalUpdated ++
}
} else {
If ($IncrementVersion -eq $true)
{
Write-Host " - The MP version would have been updated from $CurrentVersion to $NewVersion."
$iTotalUpdated ++
}
}
}
Write-Host ""
}

If ($WhatIf -eq $true){
Write-host "Total number of unsealed management packs would have been updated: $iTotalUpdated" -ForegroundColor Green
} else {
Write-host "Total number of unsealed management packs have been updated: $iTotalUpdated" -ForegroundColor Green
}

Write-Host "Done"
#endregion
</Script></ScriptBody>
<Parameters>
<Parameter>
<Name>BackupBeforeModify</Name>
<Value>$Config/BackupBeforeModify$</Value>
</Parameter>
<Parameter>
<Name>BackupLocation</Name>
<Value>$Config/BackupLocation$</Value>
</Parameter>
<Parameter>
<Name>IncrementVersion</Name>
<Value>$Config/IncrementVersion$</Value>
</Parameter>
<Parameter>
<Name>WhatIf</Name>
<Value>$Config/DetectOnly$</Value>
</Parameter>
<Parameter>
<Name>CommonMP1</Name>
<Value>$Config/CommonMP1$</Value>
</Parameter>
<Parameter>
<Name>CommonMP2</Name>
<Value>$Config/CommonMP2$</Value>
</Parameter>
<Parameter>
<Name>CommonMP3</Name>
<Value>$Config/CommonMP3$</Value>
</Parameter>
<Parameter>
<Name>CommonMP4</Name>
<Value>$Config/CommonMP4$</Value>
</Parameter>
<Parameter>
<Name>CommonMP5</Name>
<Value>$Config/CommonMP5$</Value>
</Parameter>
</Parameters>
<TimeoutSeconds>$Config/TimeoutSeconds$</TimeoutSeconds>
</WriteAction>
</MemberModules>
<Composition>
<Node ID="PSScript"/>
</Composition>
</Composite>
</ModuleImplementation>
<InputType>System!System.BaseData</InputType>
</WriteActionModuleType>