Getting information from SCCM Administration Service API

like MAC address to WOL turned off computer

ยท

6 min read

Getting information from SCCM Administration Service API

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

  • 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 image.webp

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 on Collection object
    • I have created Device information READ Security Role image.png

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 to Device information READ and limited its permissions just to one custom device collection

image.png


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 and filter parameters. Plus features like TAB completion for classes in source parameter.

IMPORTANT NOTES:

  • To import this Invoke-CMAdminServiceQuery function to your PS console, just download and dot source it
  • class names used in function source 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!

Did you find this article valuable?

Support Do it PowerShell way :) by becoming a sponsor. Any amount is appreciated!

ย