The reason I this question caught my eye was i want to act on all the references of a given CI. You know like be able to remove the references without having to hunt the individual baselines down so I can delete a CI. So I wrote this Powershell function that will remove the references from any baseline that references it. I know it is not the cleanest code but it works like a champ in my environment where I have over 700 baselines.
My Function is meant for interactive use and prompts you before it removes the CI References. If more than one CI is found matching the CIName it will ask you to be more specific.
Function Remove-CIFromBaselines {
Param (
[Parameter(Mandatory)]
[String] $CIName
)
$ciObject = (get-CMConfigurationItem -Name $CIName -fast)
$count = $ciObject.count
If ($count -gt 1) {
Write-Output "There are [$count] CIs in MECM named [$CIName]. Please be more specific..."
Break
} ELSEIF ($count -eq 0) {
Write-Output "There are [$count] CIs in MECM named [$CIName]. Please be more specific..."
Break
}
$AllBaselines= Get-CMBaseline -fast
$baselinecount = $allbaselines.count
Write-Output "There are [$baselinecount] total baselines to analyze - This could take a few minutes."
$prompt = Read-host -Prompt "Are you sure you want to remove All Referennces to [$CIName]? (Y/N) "
If ($Prompt -ne "Y") {Break}
$prompt = Read-host "Type `'I ConFirm`' to continue"
If ($Prompt -eq "I Confirm" -and $prompt -cmatch "I ConFirm") {
$CIID = $CIObject.CI_ID
$LastIndex = $CIobject.CI_UniqueID.lastIndexof("_") +1
$length = $CIObject.CI_UniqueID.substring($lastIndex).length - 2
$CIUniqueID = $CIObject.CI_UniqueID.substring($lastIndex,$length)
Write-Output "The CIUniqueID is [$CIUniqueID]"
$affectedList = New-Object System.Collections.ArrayList
$modifiedList = New-Object System.Collections.ArrayList
ForEach ($baseline in $AllBaseLines) {
$baselineName = $Baseline.localizedDisplayName
Write-Output "Analyzing [$baselineName] for reference to [$CIName]"
$XMLContent = $baseline | get-CMBaselineXMLDefinition
If ($XMLContent.contains($CIUniqueID)){
$AffectedList.Add($BaselineName) |out-Null
Write-Output "[$baselineName] contians [$CIName]"
# Check if it is a OS or An Application CI - 3 = OS ; 5 = Required Application CI - https://learn.microsoft.com/en-us/mem/configmgr/develop/reference/compliance/sms_configurationitemlatestbaseclass-server-wmi-class
If ($CIObject.CIType_ID -eq 3) {
$Baseline |Set-CMBaseline -RemoveOSConfigurationItem $CIObject.CI_ID
$Modifiedlist.Add($Baselinename) |out-null
}
If ($CIObject.CIType_ID -eq 5) {
$Baseline |Set-CMBaseline -RemoveRequiredConfigurationItem $CIObject.CI_ID
$Modifiedlist.Add($Baselinename) |out-Null
}
}
}
$countofAffected = $AffectedList.count
$countofmodified = $ModifiedList.Count
Write-Output "#################################### SUMMARY ####################################################"
Write-Output "There were [$countofAffected] Baselines that contain [$CIName]. [$countofmodified] were updated to remove the reference to [$CIName]"
If ($countofAffected -eq $countofmodified) {
ForEach ($item in $AffectedList) {
Write-Output "Baseline [$item] contained [$CIName]"
}
ForEach ($item in $ModifiedList) {
Write-Output "[$CIName] was removed from [$Item]"
}
}
Write-Output "#################################################################################################"
} ELSE {
Write-Output "Bailing since you did not confirm"
}
}
Hope this helps.