Convert ConfigMgr Error Codes to Plain Text Messages for Reporting – Part 2


I demoed this at MMS Jazz 2019 Tip and Tricks. This is Part 2 of a 3-part series. Part 1 covers how to create a PowerShell script to lookup error messages. Part 3 covers how to create a Power BI function to use an Azure Function.


I had heard of Azure Functions and I’ve written web API’s but I had never put the 2 together until I ran into this dilemma. I was trying to get the error text from ConfigMgr deployments into Power BI and ended up messing with Azure Functions to see if it was a viable alternative. This post is based on Part 1 which covers sourcing the files and creating a PowerShell script to look up error message. I’ll cover how to create an Azure Function App in this post.

Creating an Azure Function App

This next bit should be pretty easy since it’s mostly just stepping through Azure Function wizards. Once you have all of the files gathered, you simply need to create an Azure function. Log into your Azure Tenant. Search for Function App and browse to it.

A Square Dozen Image

Click Add to create a new Function App

A Square Dozen Image

This wizard change significantly since I began working on this, so if you are viewing this in the future and it’s different than shown, just follow the wizard. The main considerations are:

  • Resource Group - Create a new resource group or re-use an existing one
  • Function App name - Since you can use this app to run many functions, this should be a relatively generic name that covers the purpose of your web API. Also, this will be a public facing name, so it will need to be unique and may be unavailable if you try using something too general.
  • Runtime stack - Be sure to select PowerShell Core as your Runtime stack. I tried using the C# stuff but couldn’t get the DLL to load on .NET Core, though I’ll admit, I didn’t spend a ton of time on it.

A Square Dozen Image

For Hosting I just accepted the defaults.

A Square Dozen Image

I chose to enable Application Insights. This will likely add cost to your functions (I don’t know for sure), but it will allow you to have visibility into your functions.

A Square Dozen Image

On Tags, I didn’t enter any.

A Square Dozen Image

On the summary page, review everything then click Create.

A Square Dozen Image

Once it has been created, you can navigate to your new Azure Function App where you can configure it and begin creating your functions.

A Square Dozen Image

Creating An Azure Function

To create a new Azure Function. Click Functions then click New function. I found that clicking the + next to Functions doesn’t allow you to change the function name. It’s great if you want to create a sample function to test with though.

A Square Dozen Image

Select HTTP Trigger as the function type.

A Square Dozen Image

Give the new function a name and configure the Authorization Level. I chose Function. This will case the API to pass a Code query string parameter for authorization. During testing, I was just using Anonymous which excludes the Code string. Choose an option that fits your security needs.

A Square Dozen Image

Once the new function has been created, you will have a fully functioning ‘Hello World’ Azure Function. You can test it if you’d like by clicking Save and run. I used this template as the basis for my function.

A Square Dozen Image

In the web console editor, replace the default function code with the following code. This code is similar to what I used in Part 1 of this series, but it has been modified to work as a web API function.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
using namespace System.Net

# Input bindings are passed in via param block.
param($Request, $TriggerMetadata)

$DLLPath = Join-Path -Path $PSScriptRoot -ChildPath "bin\SrsResources.dll"
Add-Type -Path $DLLPath

# Write to the Azure Functions log stream.
Write-Host "PowerShell HTTP trigger function processed a request."

# Interact with query parameters or the body of the request.
$ExitCode = $Request.Query.ExitCode
if (-not $ExitCode) {
    $ExitCode = $Request.Body.ExitCode
}

$Language = $Request.Query.Language
if (-not $Language) {
    $Language = $Request.Body.Language
}

If(!($Language)) {
    $Language = "en-US"
}

[int]$intCode = $ExitCode

if ($intCode -eq 0 -or $intCode) {
    $Message = [SrsResources.Localization]::GetErrorMessage($intCode,$Language)
    If($Message) {
        $status = [HttpStatusCode]::OK
        $body = ($Message -replace "`n"," ") -replace "`r",""
    }
    else {
        $status = [HttpStatusCode]::OK
        $body = "No Result."
    }
}
else {
    $status = [HttpStatusCode]::BadRequest
    $body = "Please pass an ExitCode on the query string or in the request body. example: <URL>?ExitCode=0x87D00664"
}

# Associate values to output bindings by calling 'Push-OutputBinding'.
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
    StatusCode = $status
    Body = $body
})

It should look like this whenever you are done.

A Square Dozen Image

For this test case, the function requires extra files. If you don’t have the same need, you can skip the next section.

Adding Files to the Azure Function

Once you’ve updated the run.ps1 file. navigate to the main Function App node. Click Platform features then Advanced Tools (Kudu).

A Square Dozen Image

Select The Debug console drop down and select PowerShell

A Square Dozen Image

Navigate using the upper pane to get to the folder for your new Azure Function website. My path is D:\home\site\wwwroot\GetErrorMessage

A Square Dozen Image

Drag the Bin folder and it’s contents into the root of your site’s folder. You can watch the progress indicator to see when the upload has been completed.

A Square Dozen Image

Verify that the folder and contents are present.

A Square Dozen Image

Testing the Azure Function

  1. Return to your Azure Function.
  2. In the right hand pane, click Test.
  3. Click Add parameter
  4. Create query parameter for ExitCode and add an error code
  5. Create query parameter Language and add a language code.
  6. Click Save
  7. Click Run
  8. The output box should show the result.

A Square Dozen Image

You can also click on Get function URL to run the function directly in a web browser or anything else.

A Square Dozen Image

Your URL will be the base URL including your function authentication code (unless you chose anonymous when you set up the function.

https://asdconfigmgrfn.azurewebsites.net/api/GetErrorMessage?code=fasweAWDAWDFAWF/ADwdawdafASEFSE==

Then you will append your parameters to the URL like with &

&ExitCode=0x87D00664
&Language=en-US

With the final URL being [https://asdconfigmgrfn.azurewebsites.net/api/GetErrorMessage?code=fasweAWDAWDFAWF/ADwdawdafASEFSE==&ExitCode=0x87D00664&Language=en-US](https://asdconfigmgrfn.azurewebsites.net/api/GetErrorMessage?code=jcctioioyOCFDr584iP0F/nUyGHCkPldlRJvM8xxajm9pGUoToLq4A==&ExitCode=0x87D00664&Language=en-US)

A Square Dozen Image

Summary

As you can see, you can basically take ‘any’ PowerShell code and stick it into an Azure Function with a little bit of modification. For my use-case I just wanted to get error codes for reporting, but you could easily move PowerShell utility scripts to Azure Functions and leverage them in ConfigMgr task sequences or just about anywhere else. I love the idea of being able to build an API in a matter of minutes with almost no real dev work involved. Hopefully this will inspire you to check out Azure Functions!

Check out Part 1 and Part 3