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.
Hi Peter – I love this script. Deceptively simple but so useful. Thanks for sharing.
I just got a question, is it suppose to be slow. on my system, i have a collection of 1669 machines and i am deviding it up by 4, but so far it’s only on the 2 collection and its already been 20 minutes. Just checking to see if that is normal or not
It does contain a lot of filter actions, but not a lot of query actions. So I can’t really explain why it would be that slow.
I just tried the script and it works but agree there is a performance issue. I was trying to split a collection of 3500 members into 4 collections. After 5 minutes of the script running, it had only added 150 members to the first collection.
I looked in the help for Add-CMDeviceCollectionDirectMembershipRule, Intellisense indicates you can pass an array of ResourceID’s to the ResourceID parameter but in practice/the help documentation says otherwise. Kept throwing errors when I would try to run it.
I ended up using a query rule that filtered the members of the original collection based on the device SMSUniqueIdentifier attribute. That attribute uses hexadecimal characters so I filtered from 0-3, 4-7, 8-B, C-F in each query rule.
Thank you for the feedback, Mike!
This script looks very helpful indeed… I am currently trying to create multiple collections from a .txt file but I must be doing something wrong because my script only creates 1 collection. Any suggestions?
Hi D.A.C.,
Not sure. You should provide a little more information about what you’re doing to achieve that. It sounds like you’re not looping through your TXT-file.
Regards, Peter
Hi Peter
I’m looking for your full script since Technet is dead.
Can you tell me where I could get it please?
Thanks
Hi Girardy,
I’ll check my archives.
Regards, Peter
Thanks Peter
Hi Girardy,
You can find it here: http://web.archive.org/web/20200318062640/https://gallery.technet.microsoft.com/Divede-a-collection-into-2b7302d4
Regards, Peter