PowerShell Script Create Operational SCCM Collections

Benoit LecoursPowershell, SCCM26 Comments

PowerShell Script Create Operational SCCM collections

In each SCCM project that I get involved, I get the same question : “Can you create a collection for Servers, Laptops, Workstation, Windows 7, Windows 8, ect…”

With time I built a set of “Default” query for device collections that I create right after the initial SCCM setup.

This set of collection usually covers 95% of the initial client needs. I’ve built a PowerShell script so the effort to create 56 collections is near to none.

By running the Powershell script, you’ll end up having 56 collections in a Operational folder. The collections are set to refresh on a 7 days schedule.

PowerShell Script Create Operational SCCM collections PowerShell Script Create Operational SCCM collections

Full collections list

  • All Clients
  • All Clients Active
  • All Client Inactive
  • All Clients R2 CU0
  • All Clients R2 CU1
  • All Clients R2 CU2
  • All Clients R2 CU3
  • All Clients R2 CU4
  • All Clients R2 CU5
  • All Clients R2 SP1
  • All Clients R2 SP1 CU1
  • All Clients R2 SP1 CU2
  • All Clients R2 SP1 CU3
  • All Clients 1511
  • All Clients Not Reporting HW since 14 days
  • All Clients X86
  • All Clients X64
  • All Clients not Latest
  • All Laptops
  • All Dell Laptops
  • All HP Laptops
  • All Lenovo Laptops
  • All SCCM Distribution Points
  • All SCCM Site Servers
  • All SCCM Site Systems
  • All Servers
  • All Servers Physical
  • All Servers Virtual
  • All Servers Windows 2003 or 2003 R2
  • All Servers Windows 2008 or 2008 R2
  • All Servers Windows 2012 or 2012 R2
  • All Systems Created Since 24h
  • All Systems Disabled
  • All Systems Non Client
  • All Systems Obsolete
  • All Systems with SCCM Console
  • All Workstations
  • All Workstations Windows 7
  • All Workstations Windows 8
  • All Workstations Windows 8.1
  • All Workstation Windows 10
  • All Workstations Windows XP
  • All Windows Update Agent Version Outdated
  • Mobile Devices – All Android
  • Mobile Devices – All Ipad
  • Mobile Devices – All Iphone
  • Mobile Devices – All Windows RT
  • Mobile Devices – All Windows 8
  • Mobile Devices – All Windows 8.1

Note : The collection name must be unique in SCCM so if you already have a collection with the same name, the script will give an error on this particular collection but will continue to process other collections.

Tip : You can comment out any collections that you don’t want using (#) at the begging of the “New/Add-CMCollection” lines in the “Create Collection” Section.


#New-CMDeviceCollection -Name $Collection1.Name -LimitingCollectionName $LimitingCollection -RefreshSchedule $Schedule -RefreshType 2

#Add-CMDeviceCollectionQueryMembershipRule -CollectionName $Collection1.Name -QueryExpression $Collection1.Query -RuleName $Collection1.Name


The script can be downloaded from my GitHub.

Be sure to rate the submission is you are using it. Thanks !

Extra hint : You can also verify if your collection has been created properly in your collections with our  Configuration Manager – Collections report

Simply sort by the Operational folder name

SCCM Collection query

[purchase_link id=”1378″ style=”button” color=”white” text=”Report | Configuration Manager – Collections” direct=”true”]


***Update 2016-08-08 – Addition of 6 new collections.

***Update 2016-02-16 – Complete revamp of all the collections names and addition of 3 new collections.

***Update 2015-08-12 – Collections updated  for R2 SP1, CU1 client versions and Windows 10  (4 new collections)

***Update 2015-05-15 – Collections updated  for SP1 and all CU client versions (5 new collections)

***Update 2015-02-02 – Collection #4 updated  for Cu4

26 Comments on “PowerShell Script Create Operational SCCM Collections”

  1. Pingback: How to use SCCM dynamic queries in your deployment collections – IT Blog – Philip Loftin

  2. Script has already been run or a collection name already exist. Delete All Operational collection before re-executing the script !

    i cant fix this issue

  3. This substance is composed exceptionally well about explaining how to strengthen security and separate Intune with Configuration Manager infrastructure in SCCM console. Your utilization of organizing when mentioning your focuses makes your objective facts clear and straightforward. Much obliged to you.

  4. Hi, nice script if you need all Vendor | Modells PS.: first create the folder Modell in root …
    Begin {
    #Load Configuration Manager PowerShell Module
    Import-module ($Env:SMS_ADMIN_UI_PATH.Substring(0,$Env:SMS_ADMIN_UI_PATH.Length-5) + ‘\ConfigurationManager.psd1’)

    #Get SiteCode
    $SiteCode = Get-PSDrive -PSProvider CMSITE

    #Write-host “SiteCode: $($SiteCode)”
    Set-location $SiteCode”:”

    # Determine SiteCode from WMI
    try {
    Write-Verbose “Determining SiteCode for Site Server: ‘$($SiteServer)'”
    $SiteCodeObjects = Get-WmiObject -Namespace “root\SMS” -Class SMS_ProviderLocation -ComputerName $SiteServer -ErrorAction Stop
    foreach ($SiteCodeObject in $SiteCodeObjects) {
    if ($SiteCodeObject.ProviderForLocalSite -eq $true) {
    $SiteCode = $SiteCodeObject.SiteCode
    Write-Debug “SiteCode: $($SiteCode)”
    catch [Exception] {
    Throw “Unable to determine SiteCode”

    #Refresh Schedule
    $Schedule = New-CMSchedule –RecurInterval Days –RecurCount 7

    #Create Defaut Folder
    $CollectionFolder = @{Name = “Modell”; ObjectType = 5000; ParentContainerNodeId = 0}
    Set-WmiInstance -Namespace “root\sms\site_$($SiteCode.Name)” -Class “SMS_ObjectContainerNode” -Arguments $CollectionFolder

    #Create Default limiting collections
    $LimitingCollection = “All Systems”

    #Create Defaut FolderPath
    $FolderPath = $SiteCode + “:\DeviceCollection\” + $CollectionFolder.Name

    # ArrayList to store the vendor | models in
    $ClientsArrayList = New-Object -TypeName System.Collections.ArrayList
    $CollectionModelsArrayList = New-Object -TypeName System.Collections.ArrayList

    # Enumerate through all models
    $Clietns = @()
    $Clietns = Get-WmiObject -Namespace “Root\SMS\Site_$($SiteCode)” -computer $SiteServer -Class SMS_G_System_COMPUTER_SYSTEM | Select-Object -Property Manufacturer, Model

    Process {

    # Add model to ArrayList if not present
    if ($Clietns -ne $null) {
    foreach ($ArrayClient in $Clietns) {
    foreach ($Client in $ArrayClient) {
    if (!($ClientsArrayList -match $Client.Model)) {
    $PSO = [PSCustomObject]@{Name = $Client.Manufacturer+” | “+$Client.Model; Query = “select SMS_R_System.ResourceId, SMS_R_System.ResourceType, SMS_R_System.Name, SMS_R_System.SMSUniqueIdentifier, SMS_R_System.ResourceDomainORWorkgroup, SMS_R_System.Client from SMS_R_System inner join SMS_G_System_COMPUTER_SYSTEM on SMS_G_System_COMPUTER_SYSTEM.ResourceId = SMS_R_System.ResourceId where SMS_G_System_COMPUTER_SYSTEM.Model = “+'”‘+$Client.Model+'”‘}
    $ClientsArrayList.Add($PSO) | Out-Null

    #Create Collections Model
    if ($ClientsArrayList.Count -ge 1) {
    foreach ($Collection in $ClientsArrayList) {
    #if ($Collection.Name -eq “Dell Inc. | PowerEdge 2950”) {
    New-CMDeviceCollection -Name $Collection.Name -Comment “Modell” -LimitingCollectionName $LimitingCollection -RefreshSchedule $Schedule -RefreshType 2 | Out-Null
    Add-CMDeviceCollectionQueryMembershipRule -CollectionName $Collection.Name -QueryExpression $Collection.Query -RuleName $Collection.Name
    Write-host *** Collection $Collection.Name created ***
    Move-CMObject -FolderPath $FolderPath -InputObject (Get-CMDeviceCollection -Name $Collection.Name)
    End {
    #Write-Output $ModelsArrayList
    #Write-Output $CollectionModelsArrayList | Format-Table -Wrap
    #Write-Output $FolderPath

  5. Hello Benoit,

    If I have the names of hosts on which I need to install a package, how would I go about it using PS (Did not find any such option in GUI)? Just to be more clear on query, I’ve a list of Win10 hosts on which I need to deploy a package. These set of hosts are among a larger set of Win10 hosts and have difference only in terms of custom environment variables. I did not find a way to capture environment variables using custom query in GUI and hoping PS may have some answer to this.


  6. This script doesn’t work right with SCCM 1511. (console/site version of 5.00.8325.1000).

    It keeps failing saying
    “Script has already been run or a collection name already exist. Delete All Operational collection before re-executing the script!”

    The only collections that I have are
    All Systems
    All Unknown Computers
    All Desktop and Server Clients
    All Mobile Devices

    And none of those can be deleted.
    Any Suggestions?

    1. Found the faulting issue

      New-CMDeviceCollection -Name $Collection11.Name -Comment “All physical servers” -LimitingCollectionName $Collection10.Name -RefreshSchedule $Schedule -RefreshType 2 | Out-Null
      Add-CMDeviceCollectionQueryMembershipRule -CollectionName $Collection11.Name -QueryExpression $Collection11.Query -RuleName $Collection11.Name
      Write-host *** Collection $Collection11.Name created ***

      This just causes the process to not continue.

  7. Benoit, I downloaded the script from technet today. Used on a newly deployed lab, but got an error trying to create the collections. It appears that you are trying to create collection 53 and collection 68 with the same name but diff query. I changed my downloaded script on collection 68 to 1610 for the name.

  8. Noticed the collection for 1606 clients was not working and the criteria is looking for client version 5.00.8412.1006. That should be 1007, right?

  9. The “All Windows Update Agent Version Outdated – Win7 RTM and lower” collection is picking up all my Windows 10 workstations for some reason??

    1. This is weird… there’s a filter on the OS Version in the query. (SMS_G_System_OPERATING_SYSTEM.Version <= '6.1.7600'). Can you check the OS Version in the SCCM DB on some Windows 10 devices to see what is this value. Windows 10 version should be 10.%

  10. This is a great script, i’ve used it here and its covered almost everything. Just need to add in Windows 10 and maybe at the top a variable to allow changing the default refresh time from 7 days to something else

      1. It appears that some versions and editions of Windows 10, such as the Windows 10 Enterprise LTSB, do not follow the traditional naming convention. This affections Collections 8, 13, and 45.

        From my testing using “where OperatingSystemNameandVersion like ‘%Workstation 10.0%’ or OperatingSystemNameandVersion like ‘%Windows 10%'” should get all over the flavors.


        P.S. I haven’t tested Windows 10 mobile yet.

Leave a Reply