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
Let me know if you have any questions or suggestions for improvement of this script.
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
[…] the associated BIOS and Driver cab files. The SCCM Query integration uses code sources from Get Device Models in ConfigMgr 2012 with PowerShell #> # Define Sources & SCCM Sources $DellDownloadList = […]
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.
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?
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
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.
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.
$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.