Getting information from SCCM Administration Service API
like MAC address to WOL turned off computer
SCCM (now MECM) WMI contains a lot of valuable information about your environment, devices etc. In our company we have currently came across the situation, when we needed MAC addresses of computers managed by SCCM. The reason behind this was to give our users option to wake their remote computers by WOL, just by creating JIRA ticket.
We of course could've created admin account on SCCM server and utilize WMI to get such information, but there is nicer way and that is to use native SCCM REST API called Administration Service :)
In this blog post I will show you, how to use this API to your advantage.
Table of Contents
- Prerequisites
- Steps to make this work
- Benefits over using WMI
- Summary
Prerequisites
- SCCM with installed Administration Service role (SMS provider)
- Account that has at least READ rights on SCCM (or part of its data) or be SCCM admin to define security roles and assign it to some account
- Network access to SCCMs 443 port (https)
Steps to make this work
1. Find out, where the information you need is stored
Administration Service offers two data sources. WMI and v1.0 (i.e. WMI migrated to new OData/SQL model). So there are two URLs for requests:
https://<SCCMServerFQDN>/AdminService/wmi/
https://<SCCMServerFQDN>/AdminService/v1.0/
1.1 Case 1 - I know the exact WMI class, that contains information I need
- In case you know, in what class are data you need stored, you can happily proceed to next section
1.2 Case 2 - I don't know the WMI class, that contains information I need
- Use Google
- Use WMI Explorer to connect to your SCCM server WMI
ROOT\SMS\site_<yourSCCMsiteCode>
and try to find the right class on your own
1.2.1 Check v1.0 source, if the information you are looking for, isn't there
- In browser running under user, that has admin rights for SCCM open
https://<SCCMServerFQDN>/AdminService/v1.0/
or check List all available classes section in Examples bellow
2. Create SCCM Security Role
This step is necessary only if you don't want to use any of the predefined Security Roles.
For testing purposes, its ok to just use your SCCM admin account and omit this part
Security Roles allows you to delegate permissions to various part of SCCM. So you can create role, that will grant just read permissions over devices in some particular collection, read Bitlocker Recovery keys etc.
Create Security Role for reading device information
- just create new Security Role as shown bellow with just
READ
permission onCollection
object- I have created
Device information READ
Security Role
- I have created
PS: Administration Service doesn't need any special privileges, it's just another option users have to access SCCM data (instead of console or WMI)
3. Add (service) account to created Security Role
Create Active Directory user and add him to the Security Role in SCCM
- This account will be used for requesting information from API later
- I have created
svc_WOL-CCM-READ
user domain account for this purpose, added it toDevice information READ
and limited its permissions just to one custom device collection
- I have created
4. Request the data from Administration Service API
In examples bellow, I use my Invoke-CMAdminServiceQuery PowerShell function.
The "make connection" part of the function is completely taken from github.com/CharlesNRU/mdm-adminservice/blob.. so kudos to that author. I've just generalized it and added the "query" part i.e.
source
,select
andfilter
parameters. Plus features like TAB completion for classes insource
parameter.
IMPORTANT NOTES:
- To import this Invoke-CMAdminServiceQuery function to your PS console, just download and dot source it
class
names used in functionsource
parameter ARE CASE SENSITIVE!- Run function under user with READ permissions to data you are trying to obtain! Or use
Credential
parameter to supply the right credentials**
So for my goal of getting device MAC address I had to run it like
$credential = Get-Credential -UserName MYDOMAIN\svc_WOL-CCM-READ -Message "Enter svc_WOL-CCM-READ password"
$MacAddrList = Invoke-CMAdminServiceQuery -Source "wmi/SMS_R_SYSTEM" -Filter "Name eq 'PC-01'" -Select MACAddresses -Credential $credential
# and result is
MACAddresses
------------
{00:15:5D:4A:70:F2, 00:15:5D:5B:35:A0, 00:15:5D:6D:19:AB, 00:15:5D:87:DF:7E, 00:15:5D:F4:06:1C, 7C:2A:31:2...
And thats it! Just filter out MAC Addresses of virtual NIC (starts with 00:15:5D) and you are good to go ๐
Other examples:
1. List all available classes
# get all available WMI classes
Invoke-CMAdminServiceQuery -Source "wmi/" -ServerFQDN SCCMServerFQDN
# FYI you can output the result to Out-GridView to get easy filtering option
Invoke-CMAdminServiceQuery -Source "wmi/" -ServerFQDN SCCMServerFQDN | Select Name | Out-GridView
2. List all 'new OData/SQL' classes
Invoke-CMAdminServiceQuery -Source "v1.0/" -ServerFQDN SCCMServerFQDN
3. Get application deployments
Invoke-CMAdminServiceQuery -Source "wmi/SMS_ApplicationAssignment" -ServerFQDN SCCMServerFQDN -Select ApplicationName,CollectionName
4. Get application installation status
function Get-StatusType {
param ([int] $statusType)
switch ($statusType) {
1 { "Success" }
2 { "In Progress" }
3 { "Requirements not met" }
5 { "Error" }
default {$statusType}
}
}
function Get-EnforcementState {
# https://docs.microsoft.com/en-us/mem/configmgr/develop/reference/sum/sms_updatecompliancestatus-server-wmi-class
param ([int] $enforcementState)
switch ($enforcementState) {
1000 {"Success"}
1001 {"Already compliant"}
1002 {"Simulate Success"}
2000 {"In progress"}
2001 {"Waiting for content"}
2002 {"Installing"}
2003 {"Restart to continue"}
2004 {"Waiting for maintenance window"}
2005 {"Waiting for schedule"}
2006 {"Downloading dependent content"}
2007 {"Installing dependent content"}
2008 {"Restart to complete"}
2009 {"Content downloaded"}
2010 {"Waiting for update"}
2011 {"Waiting for user session reconnect"}
2012 {"Waiting for user logoff"}
2013 {"Waiting for user logon"}
2014 {"Waiting to install"}
2015 {"Waiting retry"}
2016 {"Waiting For Presentation Mode"}
2017 {"Waiting for orchestration"}
2018 {"Waiting for network"}
2019 {"Pending App-V Virtual Environment Update"}
2020 {"Updating App-V Virtual Environment"}
3000 {"Requirements not met"}
3001 {"Host Platform Not Applicable"}
4000 {"Unknown"}
5000 {"Deployment failed"}
5001 {"Evaluation failed"}
5002 {"Deployment failed"}
5003 {"Failed to locate content"}
5004 {"Dependency installation failed"}
5005 {"Failed to download dependent content"}
5006 {"Conflicts with another application deployment"}
5007 {"Waiting retry"}
5008 {"Failed to uninstall superseded deployment type"}
5009 {"Failed to download superseded deployment type"}
5010 {"Failed to updating App-V Virtual Environment"}
default { $enforcementState }
}
}
# you can narrow down the selection to specific application using -Filter "AppName eq 'SomeApp'"
Invoke-CMAdminServiceQuery -Source "wmi/SMS_AppDeploymentStatus" -Select AppName, StatusType, Total, CollectionName , EnforcementState | select AppName, @{n = 'Type'; e = { Get-StatusType $_.AppStatusType } }, @{n = 'EnforcementState'; e = { Get-EnforcementState $_.EnforcementState } }, CollectionName, Total
5. Get SCCM scripts
Invoke-CMAdminServiceQuery -Source "v1.0/Script" -ServerFQDN SCCMServerFQDN | Select ScriptName, ScriptContent
Benefits over using WMI
- Admin rights not needed
- Security scoping options i. e. you can granularly limit what information particular account will be able to retrieve
- Firewall friendly (tcp 443)
- Accessible through CMG
- Its equally fast as getting information from WMI (both took approximately 300ms). You can test it yourselves via
Measure-Command { Invoke-CMAdminServiceQuery -Source "wmi/SMS_R_SYSTEM" -Filter "name eq 'PC-01'" -Select MACAddresses}
Measure-Command { Get-CimInstance -Class SMS_R_SYSTEM -Namespace "ROOT\SMS\site_$_SCCMSiteCode" -ComputerName $_SCCMServer -Property MacAddresses -Filter "name = 'PC-01'"}
Summary
This built-in API is really great to to get information from SCCM, no matter if you need it for WOL as I did, or to get some information to your Task Sequence or PowerShell script. For more information, I recommend to check this post
If you have any questions, don't hesitate to give me some comment bellow!