Finding True Empty Collections

I recently during a migration had a need to get a list of empty collections in ConfigMgr 2007 as we were looking for areas to cleanup before starting a migration. I found a couple of PowerShell scripts already made but they didn’t do what I was looking for.

I started with this very useful script from Trevor Sullivan, I ran the script first with no errors but it returned no results. I knew the customer had empty collections so I looked into it a bit more.

As you know as well as direct membership you can also have query rules which perform queries against your resources based on any number of properties to populate queries. Trevor’s script was returning collections as memberships even with the query rules which do not return any resources.

My customer had invested heavily in the use of query rules to populate their collections so I needed a way to find out a true membership count from the database after the collection evaluator has ran.

This lead me to the SMS_Collection class and the GetNumResults method. However when you try and call this in PowerShell it doesn’t work. I found a Manageability Guys blog post on this and used the script sample at the bottom to help call the invoke the method in PowerShell.

This got me a list of zero membership collections and included query rule membership as well. When I checked some of the collections they were parents for collections which did have members, this was something I didn’t want because I wanted to migrate the sub collections. I then looked at the GetTotalNumResults method in the same SMS_Collection class. This was what I was looking for as this includes members of sub collections meaning I got a very accurate list.

Here is the script I ended up using. If the formatting doesn’t work well, please find it on my SkyDrive: http://sdrv.ms/12Q1IoA

function Get-CollectionCount
{ 
    [CmdletBinding()] 
    PARAM 
    ( 
        [Parameter(Position=1)] $CollectionID       
    ) 
    Process 
    { 
        $Collectionnamespace = "\\SERVER01\root\sms\site_SITECODE:SMS_Collection" 
    $collobject = Invoke-WmiMethod -Path $collectionNameSpace –Name GetTotalNumResults -ArgumentList $collectionID,$Whatever 
    Set-Variable -Name CollectionCount -Value $collObject.Result -Scope global
    } 
}

$Server = 'SERVER01'
$Exclude = ,'COLLROOT'
$Namespace = 'root\sms\site_SITECODE'

$Collections = Get-WmiObject -Namespace $Namespace -Class SMS_Collection -ComputerName $Server

foreach ($Collection in $Collections)
{
    Get-CollectionCount $Collection.CollectionId
    
    if ($CollectionCount -eq 0)
    {
        Write-Host ("Empty Collection ID: " + $Collection.CollectionID + " (Name: " + $Collection.Name + ")")
    }
}
Advertisements

Tags: , , , , ,

About Martyn

Martyn is one of the Senior Cloud Architects and DevOps Team Leader at one of the worlds leading Cloud Transformation Specialists Inframon. Martyn is responsible for the architecture of some of the largest Azure deployments in EMEA and is a advisor to a many businesses on their strategies. Martyn is a regular speaker at Microsoft events and community events on Azure and DevOps, giving his insight to a growing number of audiences.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: