I recently had to create a bunch of collections based upon the device models present in ConfigMgr at a customer. Before I could go ahead and create the collections, I needed to know what models was present in the environment. I therefor created a small PowerShell script that would output objects so that they could either be exported to a CSV file or simply just sort them by property.


Save the following script as Get-CMDeviceModels.ps1 in e.g. C:\Scripts.

    Get all device models present in ConfigMgr 2012
    This script will get all device models present in ConfigMgr 2012. It requires Hardware Inventory to be enabled and that the devices have reported a full hardware inventory report at least once. 
    Site server name with SMS Provider installed 
    .\Get-CMDeviceModels.ps1 -SiteServer CM01
    Get all device models on a Primary Site server called 'CM01':
    Script name: Get-CMDeviceModels.ps1 
    Author:      Nickolaj Andersen 
    Contact:     @NickolajA 
    DateCreated: 2015-04-10 
    [parameter(Mandatory=$true, HelpMessage="Site server where the SMS Provider is installed")]
    [ValidateScript({Test-Connection -ComputerName $_ -Count 1 -Quiet})]
Begin {
    # 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"
Process {
    # ArrayList to store the models in
    $ModelsArrayList = New-Object -TypeName System.Collections.ArrayList
    # Enumerate through all models
    $Models = Get-WmiObject -Namespace "root\SMS\site_$($SiteCode)" -Class SMS_G_System_COMPUTER_SYSTEM | Select-Object -Property Model
    # Add model to ArrayList if not present
    if ($Models -ne $null) {
        foreach ($Model in $Models) {
            if ($Model.Model -notin $ModelsArrayList) {
                $ModelsArrayList.Add($Model.Model) | Out-Null
    # Output the members of the ArrayList
    if ($ModelsArrayList.Count -ge 1) {
        foreach ($ModelItem in $ModelsArrayList) {
            $PSObject = [PSCustomObject]@{
                Model = $ModelItem
            Write-Output $PSObject

Using the script

Here’s a small example of just running the script and sorting the output:

1. Open an elevated PowerShell console and browse to C:\Scripts (or the path where you’ve saved the above script).
2. Run the following command to get all device models:

.\Get-CMDeviceModels.ps1 -SiteServer CAS01 | Sort-Object -Property Model


Let me know if you have any questions or suggestions for improvement of this script.


  • Alexandr
    Posted at 16:19 April 21, 2015

    Very nice script. Do you mind me asking how to execute script for special device collection not for site server. I am afride ti execute it in my work environment, just tested it in my virtual environment.
    And one more question do you recomend me resuorce for learing Powershell for SCCM?

    • Nickolaj
      Posted at 09:12 April 22, 2015

      Hi Alexandr,

      This script was not intended to only run against a certain collection, it shows the models available in your whole hierarchy. You could probably extend the script to only search for devices that are in a particular collection, but I don’t really see the point in that.


      • Chris L
        Posted at 23:45 March 11, 2016
        Chris L

        No it really needs to be collection limited. In my case we run an SCCM CAS that covers the entire united states. I need to limit the results to a collection for each state and sometimes further to separate campuses within a state.

        • Ben
          Posted at 11:02 May 24, 2018

          i would normally agree Nickolaj… however i have just run into a client whom has over 100000 clients, only aprrox 3000 of which are servers, and i need to make hardware based collections only for the servers….

          For ChrisL, in that instance, you can use your hardware collections – and then use the location collection (which i assume you have) as a limiting collection.

      • Chris L
        Posted at 23:49 March 11, 2016
        Chris L

        $ComputerSystems = Get-WmiObject `
        -Namespace root\sms\site_DDD `
        -ComputerName SCCM01`
        -Class SMS_G_System_Computer_System

        $ComputerSystems `
        | Group-Object -Property Manufacturer,Model `
        | Where-Object { $_.Count -gt 5 } `
        | Sort-Object -Property Count -Descending

        This script is much simpler and cleaner. Easier to manipulate quickly for various queries. Just lacks the ability to limit to a collection.

  • J
    Posted at 18:07 September 25, 2015

    Good stuff. One thing to maybe add to it, on line 44 would be ” -computername $SiteServer “.
    Without that, the script can only be run from the site server itself, throwing an Invalid namespace error if run from another system, e.g. admin workstation . Feeding the gwmi command a computername, this should work from anywhere, I think.

  • James Willis
    Posted at 17:57 December 11, 2018
    James Willis

    I am getting a an error when trying to run the script.

    Get-WmiObject : Invalid namespace “root\SMS\site_CEG”
    At C:\Scripts\Get-CMDeviceModels.ps1:44 char:15
    + … $Models = Get-WmiObject -Namespace “root\SMS\site_$($SiteCode)” -Cl …
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : InvalidArgument: (:) [Get-WmiObject], ManagementException
    + FullyQualifiedErrorId : GetWMIManagementException,Microsoft.PowerShell.Commands.GetWmiObjectCommand

  • Leave a Reply

    This site uses Akismet to reduce spam. Learn how your comment data is processed.