How to locate SCCM Collection Object based on the Collection ID

1 minute read

Often, I found it’s hard to locate the Collection object in the SCCM console if you only know the Collection ID. Couple of weeks ago I ran into a situation where I need to modify the settings of a bunch of collection objects and all I knew was the Collection ID.

I wrote a script called Get-CollectionPath that identifies all possible paths to a particular collection (as a collection can be linked to multiple places).

The Syntax is: .\Get-CollectionPath <SCCM Central Site Server Name> <Collection ID>

image

Download the script here.

param([string]$CentralSiteServer,[string[]]$CollectionID)
	Function Get-CollectionName ($CollectionID)
	{
		$CollectionName = (Get-WmiObject -ComputerName $CentralSiteProvider -Namespace root\sms\site_$CentralSiteCode -Query "Select * from SMS_Collection where CollectionID = '$CollectionID'").name
		Return $CollectionName
	}
	Function Get-ParentCollectionID ($subCollectionID)
	{
		$arrParentCollectionID =@()
		$objCollectToSubCollect = Get-WmiObject -ComputerName $CentralSiteProvider -Namespace root\sms\site_$CentralSiteCode -Query "Select * from SMS_CollectToSubCollect where SubCollectionID = '$subCollectionID'"
		if (($objCollectToSubCollect.GetType()).IsArray -eq $true)
		{
			Foreach ($item in $objCollectToSubCollect)
			{
				$arrParentCollectionID += $item.ParentCollectionID
			}
		} else {
			$arrParentCollectionID += $objCollectToSubCollect.ParentCollectionID
		}
		Return $arrParentCollectionID
	}

	Function Get-CollectionPathObject ($strBaseCollectionPath, $CollectionID)
	{
		$CollectionName = Get-CollectionName $CollectionID
		if ($strBaseCollectionPath -eq $null) {$strBaseCollectionPath = "$CollectionName($CollectionID)"}
		$arrParentID = Get-ParentCollectionID $CollectionID
		$arrObjPath = @()
		Foreach ($CollectionID in $arrParentID)
		{
			$ParentCollectionName = Get-CollectionName $CollectionID
			$strCollectionPath = "$ParentCollectionName($CollectionID)\"+$strBaseCollectionPath
			$objCollectionPath = New-Object psobject
			Add-Member -InputObject $objCollectionPath -membertype noteproperty -name CollectionPath -value $strCollectionPath
			Add-Member -InputObject $objCollectionPath -MemberType NoteProperty -Name ParentCollectionID -Value $CollectionID
			$arrObjPath += $objCollectionPath
		}
		Return $arrObjPath
	}

	$objSite = Get-WmiObject -ComputerName $CentralSiteServer -Namespace root\sms -query "Select * from SMS_ProviderLocation WHERE ProviderForLocalSite = True"
	$CentralSiteCode= $objSite.SiteCode
	$CentralSiteProvider = $objSite.Machine

	$arrObjCollectionPath = new-object System.Collections.ArrayList
	$bFinished = $false
	$arrPath = Get-CollectionPathObject $strCollectionPath $CollectionID

	Foreach ($item in $arrPath) {$arrObjCollectionPath.Add($item) | Out-Null}
	Remove-Variable arrPath
	Do{
		$arrObjTempNew = @()
		$arrObjTempOld = @()
		Foreach ($item in $arrObjCollectionPath)
		{
				$objCollectionPath = Get-CollectionPathObject $item.CollectionPath $item.ParentCollectionID
				Foreach ($objPath in $objCollectionPath) {$arrObjTempNew += $objPath}
				$arrObjTempNew += $objCollectionPath
				$arrObjTempOld += $item
		}
		Foreach ($OldItem in $arrObjTempOld) {$arrObjCollectionPath.Remove($OldItem)}
		Foreach ($NewItem in $arrObjTempNew) {If (!($arrObjCollectionPath.Contains($NewItem))) {$arrObjCollectionPath.Add($NewItem) | Out-Null}}
		Remove-Variable arrObjTempOld
		Remove-Variable arrObjTempNew

		$AllReachedTop = $true
		Foreach ($item in $arrObjCollectionPath)
		{
			if ($($item.ParentCollectionID) -ne "COLLROOT") {$AllReachedTop = $false}
		}
		IF ($AllReachedTop -eq $true) {$bFinished = $true}
	} While ($bFinished -ne $true)
$arrOutput = @()
Foreach ($item in $arrObjCollectionPath) {$arrOutput += $item.CollectionPath}
$arrOutput | fl *

Leave a comment