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.

Script

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

<#
.SYNOPSIS
    Get all device models present in ConfigMgr 2012
.DESCRIPTION
    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. 
.PARAMETER SiteServer
    Site server name with SMS Provider installed 
.EXAMPLE
    .\Get-CMDeviceModels.ps1 -SiteServer CM01
    Get all device models on a Primary Site server called 'CM01':
.NOTES
    Script name: Get-CMDeviceModels.ps1 
    Author:      Nickolaj Andersen 
    Contact:     @NickolajA 
    DateCreated: 2015-04-10 
#>
[CmdletBinding(SupportsShouldProcess=$true)]
param(
    [parameter(Mandatory=$true, HelpMessage="Site server where the SMS Provider is installed")]
    [ValidateNotNullOrEmpty()]
    [ValidateScript({Test-Connection -ComputerName $_ -Count 1 -Quiet})]
    [string]$SiteServer
)
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

139_1

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

Nickolaj Andersen
Principal Consultant and Enterprise Mobility MVP since 2016. Nickolaj has been in the IT industry for the past 10 years specializing in Enterprise Mobility and Security, Windows devices and deployments including automation. Currently working for TrueSec as a Principal Consultant. Awarded as PowerShell Hero in 2015 by the community for his script and tools contributions. Creator of ConfigMgr Prerequisites Tool, ConfigMgr OSD FrontEnd, ConfigMgr WebService to name a few. Frequent speaker at conferences and user groups.

(773)

comments
  • Alexandr
    Posted at 16:19 April 21, 2015
    Alexandr
    Reply
    Author

    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
      Nickolaj
      Reply
      Author

      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.

      Regards,
      Nickolaj

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

        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.

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

        $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
    J
    Reply
    Author

    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.

  • Leave a Reply