The goal of this blog is to clarify some misunderstandings around Collections in System Center Configuration Manager. There is no right or wrong, the goal is that you understand the impact of the different scenarios.

available vs. required deployments

Create available deployments targeting User Collections if you want to publish Software in Software Center.
The SCCM Agent does not download policies for available deployments that are targeting User Collections. This is because the User gets the list of available Software from the 'Application Catalog web service point' at the time where SoftwareCenter is loading the Items. To reload the Software, just press [F5] in Software-Center, no need to request User/machine Policies..

In all other scenarios, the SCCM Agent must download and refresh the policies in WMI and Software-Center is loading the Items from WMI. Policies are downloaded in an Intervall, so it may take some time until the user will see the changes... and as more policies the Agent must manage, the risk of corrupted or orphaned policies is getting higher...

User vs. Device Collection

Use User Collections if you want to use AD-Groups for Software assignments.
On User Collections, you can add Active Directory Groups as a Direct-Membership Rule. There is no need for a scheduled or incremental collection update.

Device Collections cannot have AD Groups as Members. If you want to assign Software to AD Groups containing Devices, you must create a Query Rule to evaluate the group membership for the devices. This scenario has now a dependency on the AD Synchronization, the Collection evaluation cycle and on the machine policy refresh cycle on the agent. As a result, it can take hours until a device will get the policy for the assigned Software.


If an external Service-management solution is involved, AD Groups (and therefore User Collections) are the simplest way to automate Software assignment as most of these Tools can add Users to AD groups out of the box. -> No API or SDK knowledge required and the process does not depend on any ConfigMgr Schedules...

Direct vs. Query-Rules

avoid direct rules in large Environments or if you want to automatically (SDK, PowerShell) add members to collections.
Direct-Membership Rules are a simple way to just add a User, UserGroup or Device to a Collection, so what is wrong with that?

Every Collection has an Attribute 'CollectionRules' that contains all query and direct Rules:

instance of SMS_Collection
	CollectionID = "SP10013D";
	CollectionRules = {
instance of SMS_CollectionRuleDirect
	ResourceClassName = "SMS_R_System";
	ResourceID = 16777223;
	RuleName = "WKS3399";
instance of SMS_CollectionRuleDirect
	ResourceClassName = "SMS_R_System";
	ResourceID = 16777235;
	RuleName = "WKS3002";

Let's assume, we have a Collection with 2'000 direct Rules and we want to add a single Device (with the Console or by SDK/PowerShell).

  • Get the Collection with the Attribute 'CollectionRules', so 2'000 Rules are loaded to memory
  • We add a direct Rule, so we have 2'001 Rules in memory.
  • Save the 'CollectionRules' -> ConfigMgr has to store 2'001 Rules
  • The Collection is locked until all changes are saved. -> No one else can make any changes on the collection.

Result: The amount of direct Rules does have an impact on how long the collection is locked.

Reasons to NOT use direct Rules

If you want to automate that process, you have to implement a queue to store all changes on a locked collection, otherwise you may end up in loosing rules in ConfigMgr.

In large Environments with tenthousands of direct rules, it can take several minutes to store the changes on a collection.

Direct-Rules are storing the ResourceID of a device or user. If the device or user is deleted, all the membership rules are lost as the device/user will never get the same ResourceID again.

Never try to export/import Collections with direct rules across different ConfigMgr environments. The Device/user name (RuleName) is just for the Query-Editor... You will see all your known Names but in the background, the Objects will have a different ResourceID so you will mess up all your collection membership rules...

Query Rules

The following section contains some consideratins around query rules.


Avoid Wildcards whenever possible in query Rules as this can have a massive impact on the evaluation performance.

An example: the following Query takes 3.671s to evaluate:
... SMS_G_System_INSTALLED_SOFTWARE.ARPDisplayName like "%7-Zip%9.%"

the query without wildcard does evaluate in 1.141s:
... SMS_G_System_INSTALLED_SOFTWARE.ARPDisplayName = "7-Zip 9.20 (x64 edition)"

'OR' operations

Avoid 'OR' operations against different classes.

I've often seen the case where 'Installed Applications' and 'Installed Applications (64)' are used to get clients with a specific Software:

this is a super BAD example as the evaluation takes 475s to complete...
So what is wrong with the query?

  1. The query is using Wildcards which makes the comparisation very resource intensive. Without Wildcards, the Query evaluation time goes down to 22s
  2. The Problem is that two independent classes are involved. If a Client has the x86 Version installed, SQL will return all x64 Software-Items (and v.v.) as the two classes are linked with an 'OR' operation. In my example with 3'200 Clients the Query returns totally 1'120'000 Records...

Instead of using 'Installed Applications' and 'Installed Applications (64)' use 'Installed Software' (can be activated in the CM Console on 'Asset Intelligence' or in the Client Settings -> Hardware Inventory -> Set Classes...

The Evaluation of the following query takes 1.859s
SMS_G_System_INSTALLED_SOFTWARE.ARPDisplayName like "7-Zip 9.20%"

Summary: For the same result, we reduced the Collection Evaluation Time from 475s to 1.9s

Create two Queries, one for the Clients with the X86 Version of the Software and one for the Clients with the X64 Version. SCCM will merge the results from both Queries.


Query based Collections have to refresh in a scheduled Interval. Define the schedule with care to reduce load on the Site Server. You can use the 'CEViewer' Tool from the Microsoft Toolkit to check how long each collection requires to refresh.

also take care on the start time, specially if you create collections automatically by script. It's recommended to randomize the start time to prevent that the collection will refresh at the same time...

Incremental update

activate incremental update only on selected collections that need to be up to date (e.g. query based limiting Collections).
Query based collection with incremental flag enabled must re-evaluate as soon as an involved class is getting updated (e.g. from Hardware-Inventory).