Divide a collection into multiple smaller collections in ConfigMgr 2012 via PowerShell

This blog post will be about a question that I recently read on a forum and also already got a couple of times with different customers. That question is if it’s possible to simply create multiple smaller collections of one specific collection. This can be useful when a specific deployment has to be deployed in smaller groups then normally. Also, there are already a couple solution available in the community, like the SCCM Collection Splitter by Mickael Ponsot and the Planning an upgrade of an application  by Jörgen Nilsson, but as always, not every solution fits every customer. In my case(s) these solution didn’t fit, as it shouldn’t have to much options and it shouldn’t rely on static properties.

That’s why I created a simple PowerShell script that requires a collection and a number of collections as input. Based on that input this PowerShell script creates collections with random, but equally divided, collection members. The rest of this post will explain this PowerShell script and shows an example.

>> The complete function is available via download here on the TechNet Galleries! <<

Step 1: Get and set the start variables

The first step, like with every other script, is getting and setting variables to work with during the script. The collection name and the number of collections are input variables of this script and based on that input an array with devices will be created. I do this by using the Get-CMDevice cmdlet. Also, the number of devices per collection will be calculated. I do this by using the ceiling method of math. This will make sure that it will always round up, so we don’t have any leftovers after the script. This all together brings me to the following code:

$Devices = Get-CMDevice -CollectionName $CollectionName $NumberOfDevices = $Devices.Count $NumberOfDevicesPerCollection = ` [math]::ceiling($NumberOfDevices / $NummberOfCollections)

Step 2: Create the new collections

The second step is to create the new collections. Starting from this point the script will go through a for-loop for as many times as the number of collections to be created (see the complete script).  To make sure I create unique collections, I use the number of times it went through the for-loop as part of the collection name. Also, I simply use the New-CMDeviceCollection cmdlet to create the collections. This all together brings me to the following code:

$NewCollectionName = "Example Collection $i" New-CMDeviceCollection -Name $NewCollectionName ` -LimitingCollectionName $CollectionName

Step 3: Get and add the collection members

The third step is to get the collections members and to add them to the newly created collections. To be able to select a number of devices I use the Get-Random cmdlet that allows me to just select a specific number of random devices from an array. After that I can simply loop through those devices and create a direct membership rule per device, by using the Add-CMDeviceCollectionDirectMembershipRule cmdlet. This all together brings me to the following code:

$NewDevices = Get-Random -InputObject $Devices ` -Count $NumberOfDevicesPerCollection foreach ($NewDevice in $NewDevices) { Add-CMDeviceCollectionDirectMembershipRule ` -CollectionName $NewCollectionName -Resource $NewDevice }

Step 4 : Prepare for the next collection

The fourth, and last step, is to make all the variables ready for the next round through the for-loop. This means I’ve got to make sure that the devices that are added to the previous collection, are removed from the the array with devices. Also, it’s important to recalculate the number of devices per collection. This is to make sure that I won’t end-up with a really small collection, or, in some cases, a collection without members. This all together brings me to the following code:

$Devices = $Devices | Where-Object { $NewDevices -notcontains $_ } $NumberOfDevicesLeft = $Devices.Count $NummberOfCollectionsLeft = $NummberOfCollections-$i if ($NummberOfCollectionsLeft -gt 0) { $NumberOfDevicesPerCollection = ` [math]::ceiling($NumberOfDevicesLeft / $NummberOfCollectionsLeft) }

Result

At the end there’s nothing better then looking at a successful result. In the following screenshot the script is executed for the All Desktop and Server Clients collection to create four smaller (equally sized) collections.

ExampleCollections

Share

Leave a Comment