I've not done much work with the ConfigMgr SDK before, but a project I'm working on at the moment called for a large number of collections to be created for application distribution purposes. This is a direct replacement for ZEN Works, so to try to minimize the impact on the helpdesk we've decided to populate AD security groups with computer accounts to drive the population of the ConfigMgr collections. It's not an approach that I'm particularly in favour of as it introduces latency:
Using AD Security Groups for Collection Population | Using Direct Membership in the ConfigMgr Console |

| 
|
Assuming the worst-case scenario this approach could take:
AD Replication – 15 mins
System group Discovery – 60 mins
Colleval – 60 mins
Computer Client update – 60 mins
Maximum possible latency=3hrs 15 minutes | Assuming the worst case scenario this approach would take:
Computer Client update – 60 mins
Maximum possible latency=60 minutes |
These issues aside, I decided to have a go at creating my many application based collections using a bit of VBScript from the SDK.
I always like to create a clean collection structure from the outset with a small number of root collections with sub collections. I normally break these down as shown:
This approach keeps the collection structure tidy, but means that creating collections using COLLADD won't work as this script doesn't set the parent collection, creating everything in COLLROOT. If you're going to have to move them all manually later (by linking and then deleting the original) then you may as well create them manually in the first place.
Fortunately the SDK provides great samples on creating objects in the console, and the CreateDynamicCollection function automatically expects the Collection ID of the parent collection.
The script I have used is copied verbatim from the SDK with one minor modification to allow for escaping of the quotes around the AD System group Name:
Script1
' Setup a connection to the local provider.
Set swbemLocator = CreateObject("WbemScripting.SWbemLocator")
Set swbemconnection= swbemLocator.ConnectServer(".", "root\sms")
Set providerLoc = swbemconnection.InstancesOf("SMS_ProviderLocation")
For Each Location In providerLoc
If location.ProviderForLocalSite = True Then
Set swbemconnection = swbemLocator.ConnectServer(Location.Machine, "root\sms\site_" + Location.SiteCode)
Exit For
End If
Next
Call CreateDynamicCollection(swbemconnection, "XXX0001B", "App Blueprint", "Members will receive the application", true, "SELECT * from SMS_R_System where SMS_R_System.SystemGroupName = ""MYDOMAIN\\App Blueprint""", "App Blueprint")
'NB As the AD Group Names may have spaces in them it is necessary to escape the quotes. The above query line is wrapped for legibility.
Sub CreateDynamicCollection(connection, existingParentCollectionID, newCollectionName, newCollectionComment, ownedByThisSite, queryForRule, ruleName)
' Create the collection.
Set newCollection = connection.Get("SMS_Collection").SpawnInstance_
newCollection.Comment = newCollectionComment
newCollection.Name = newCollectionName
newCollection.OwnedByThisSite = ownedByThisSite
' Save the new collection and save the collection path for later.
Set collectionPath = newCollection.Put_
' Define to what collection the new collection is subordinate.
' IMPORTANT: If you do not specify the relationship, the new collection will not be visible in the console.
Set newSubCollectToSubCollect = connection.Get("SMS_CollectToSubCollect").SpawnInstance_
newSubCollectToSubCollect.parentCollectionID = existingParentCollectionID
newSubCollectToSubCollect.subCollectionID = CStr(collectionPath.Keys("CollectionID"))
' Save the subcollection information.
newSubCollectToSubCollect.Put_
' Create a new collection rule object for validation.
Set queryRule = connection.Get("SMS_CollectionRuleQuery")
' Validate the query (good practice before adding it to the collection).
validQuery = queryRule.ValidateQuery(queryForRule)
' Continue with processing, if the query is valid.
If validQuery Then
' Create the query rule.
Set newQueryRule = QueryRule.SpawnInstance_
newQueryRule.QueryExpression = queryForRule
newQueryRule.RuleName = ruleName
' Add the new query rule to a variable.
Set newCollectionRule = newQueryRule
' Get the collection.
Set newCollection = connection.Get(collectionPath.RelPath)
' Add the rules to the collection.
newCollection.AddMembershipRule newCollectionRule
' Call RequestRefresh to initiate the collection evaluator.
newCollection.RequestRefresh False
End If
End Sub
When executed the script automatically creates the required collection beneath my "Applications" parent collection (XXX0001B) with the query which enumerates all machines in the "APP Blueprint" AD group.