JNUC (for those that may not know) is the Jamf Nation User Conference. It is Jamf’s annual event to showcase what is new for Apple MDM management and for other Jamf administrators to show how they are using Jamf in their unique environments.

The Jamf Nation User Conference is not a sales expo or a tradeshow. Instead, it’s a welcoming, three-day rally of community and Jamf-led presentations, deep-dive education sessions, and expert product insights to discover new and better ways to manage Apple devices with the purpose of empowering people, transforming business processes and making IT life easier.

I was fortunate enough to be ask to present at this year’s JNUC in San Diego. For me, this was a great honor and achievement. As a long time user of Jamf (since the Casper Suite days), I have always wanted to partake in presenting at a JNUC conference. Above that though, having a collective group of like minded people to speak to whose focus in their daily work is to create a better experience for their end-users while maintaining a high standard of practice was amazing. There were many conversations outside of the scheduled sessions that were very beneficial. As someone who is constantly trying to self-improve and learn, this was probably the best perk of going to JNUC in person.

For this post however, I would like to go through the presentation that I gave so that hopefully it can be of help to someone else. The presentation I chose to give was “How To Keep Your Macs Up-To-Date With Microsoft Power Automate”, and we’ll dive into it now


This workflow will utilize web hooks in Jamf Pro, looking for Smart Computer Group Membership Changes to a Smart Group that identifies computers that have updates available and are eligible for the updates.


  1. To use this workflow with Jamf Pro and Microsoft Power Automate, you will need a Microsoft Power Automate Premium Per User License. This license will need to be assigned to the user under which the workflow will run.
  2. We also need to have a Jamf Pro environment with an additional API username & password for our workflow laid out here. It is good practice to build an api username with limited privileges for your specific purposes rather than use your own Jamf Pro administrator account.

Things to keep in mind:

  • Macs need to be on macOS 10.11 or later, and need to be Supervised or enrolled via Prestage enrollment
  • Silicon Macs will need a bootstrap token escrowed in Jamf Pro to install updates without user interaction

Building Automation Workflow in Power Automate

We can start building this flow by:

-Signing into Microsoft Power Automate
-Select to create a new flow
-Give your flow a name, use the flow trigger: when an HTTP request is received

After adding the trigger for our flow and saving, Power Automate will generate a unique URL for your POST requests (your incoming Webhook data from Jamf Pro). You will need to populate the Request Body JSON Schema here so that Power Automate can organize the incoming data in a way that can be used later in the flow. You can find a sample payload for this located here: Jamf Webhook Documentation

**If an error occurs for your integer, you will need to include them in quotes. (“integer”)

Once we have our trigger set up, we will need to insert some steps to initialize some variables in our flow. We will need to add (4) ‘Initialize Variable’ steps to our flow. They will be configured as follows:

  1. Name: jamfProURL
    Type: String
    Value: https://yourJamfProURL.jamfcloud.com
  2. Name: apiUsername
    Type: String
    Value: yourAPIUsername
  3. Name: apiPassword
    Type: String
    Value: yourAPIPassword
  4. Name: updateVersion
    Type: String
    Value: Leave this value blank, it will be filled by our flow later on.

**If you do not want to put your api username and password into your flow, there are some additional steps you could take to have Power Automate read the username and password from a Sharepoint list or store them inside of an Azure key vault and retrieve from your flow.

Next, we need to add another ‘Initialize Variable’ step to our flow, but this will be using a type of ‘Array’. The purpose of this variable will be to store any possible software updates that the computer has stored in the Software Updates Inventory pane in Jamf Pro. The workflow will then move through the array to find only the ‘macOS’ update version to apply. So add an additional ‘Initialize Variable’ step to your flow and configure it as follows:

  1. Name: softwareUpdatesArray
    Type: Array
    Value: Leave this value blank, it will be filled by our flow later on.

We can now make our first API call using Microsoft Power Automate. This API call will be to generate a bearer token for the Jamf Pro API which will be used for authentication in all our subsequent calls. Start by adding the ‘HTTP’ step to the flow and configure:

  1. Method: POST
    URI: jamfProURL/api/v1/auth/token
    Authentication: Basic
    Username: apiUsername
    Password: apiPassword

**It may also be helpful to rename your action here as you will be referencing it later. Here I named the action to ‘GenerateBearerToken’

We made our first API call to Jamf using Power Automate, but now we need to gather the response and filter out our bearer token received for later use. Add the ‘Initialize Variable’ step to the flow. We will configure this step as follows:

  1. Name: BearerToken
    Type: String
    Value: Our value here will use an expression to gather the value, here is the expression: body(‘GenerateBearerToken’)[‘token’]

We can finally start working with the data sent over from Jamf Pro via our Webhook. The next group of steps will need to be done for each computer that is sent over in the blob of data from Jamf Pro. For this reason, our next step will be to add the ‘Apply to each’ control step to our flow. In the ‘Select an output from previous steps’, we want to find our ‘groupAddedDevicesIds’ from the Dynamic Content list. These are our computer ids of our computer in Jamf Pro for those that were recently added to our Smart Computer Group and our flow will run through a loop of each. Our step step is to gather our available software updates for our computers. Add the ‘HTTP’ action inside of our Apply To Each step and configure:

  1. Method: GET
    URI: jamfProURL/api/v1/computers-inventory/Current item/section=SOFTWARE_UPDATES
    Headers: Accept | application/json
    Headers: Authorization | Bearer BearerToken

Our response for this API call will send over all software updates listed in that current computer id’s inventory record from Jamf Pro. Now we need to parse the data, so we need to provide a JSON schema to let Power Automate know what to expect. Let’s add the ‘Parse JSON’ operation step next. We can add the ‘Body’ response from our last call, then give it the following as a schema to follow:

    "type": "object",
    "properties": {
        "id": {
            "type": "string"
        "udid": {
            "type": "string"
        "general": {},
        "diskEncryption": {},
        "localUserAccounts": {},
        "purchasing": {},
        "printers": {},
        "storage": {},
        "applications": {},
        "userAndLocation": {},
        "configurationProfiles": {},
        "services": {},
        "plugins": {},
        "hardware": {},
        "certificates": {},
        "attachments": {},
        "packageReceipts": {},
        "fonts": {},
        "security": {},
        "operatingSystem": {},
        "licensedSoftware": {},
        "softwareUpdates": {
            "type": "array",
            "items": {
                "type": "object",
                "properties": {
                    "name": {
                        "type": "string"
                    "packageName": {
                        "type": "string"
                    "version": {
                        "type": "string"
                    "packagename": {
                        "type": "string"
                "required": [
        "groupMemberships": {},
        "extensionAttributes": {},
        "contentCaching": {},
        "ibeacons": {}

Now is the time to use our ‘softwareUpdates’ array variable. This part gets a bit weird. At this point, we need to have another ‘Apply to each’ control step added to our flow as our computers may have more than 1 update available to them. Add the ‘Apply to each’ control and add the output from our last Parse JSON step. Next, inside of our loop, add the ‘Append to array variable’. Our variable we are appending to is ‘softwareUpdatesArray’ and we want to bring in the values ‘name’,’version’ from our last step.

We now have our updates in an array variable. We need to add a condition to our flow for identifying versions of application macOS updates. The reasoning for this is that we do not want to send a version number for Xcode Command Line Tools to the computer via the Jamf Pro API if that version number does not match what the macOS update version is. At the time of creating my JNUC presentation, macOS 12.5.1 was available as an update as was Command Line Tools 13.something. I wanted my API call to send the version for a managed macOS update as 12.5.1, not 13.something, so I used a condition to look at the name of the available update, determine if it was macOS specific, and if it was, use the ‘Set Variable’ step in my flow to set the updateVersion variable to version.

It’s all downhill from there. We need to add an additional ‘HTTP’ step to send our managed macOS update command. Configure the step as:

  1. Method: POST
    URI: jamfProURL/api/v1/macos-managed-software-updates/send-updates
    Headers: Accept | application/json
    Headers: Authorization | Bearer BearerToken
  "deviceIds": [
    Current Item
  "updateAction": "DOWNLOAD_AND_INSTALL",
  "version": "updateVersion"

** Note that the referenced command above will download and install the update available automatically and forcefully. There is no user interaction required and you should modify this call to fit your organization’s needs.

Lastly, to clean things up, we should invalidate our bearer token. This will ensure that the token we generated at the beginning of our flow can’t be used elsewhere. Add a last ‘HTTP’ step to our flow, outside of our last loop. I’ll post a screenshot of what this call will look like:

Save your flow, and we can move onto setting this up in Jamf Pro. We should have a flow that looks similar to:

Making the connection in Jamf Pro

Hopefully you already have a Smart Computer Group in Jamf Pro that you would like to target. This group should have the criteria included to look for any available updates for the computers, and also any other criteria that may be helpful in the update process (such as minimum available storage, bootstrap token escrowed, battery charged %, etc, or anything you would find valuable for this group).

Create a new Webhook in Jamf Pro by navigating to Jamf Pro > Settings > Global Management > Webhooks. The Webhook URL will be the generated URL from our trigger in our Power Automate flow, copy and paste it here. Also, remember to replace all %2F characters in the URL with / or your flow will not work correctly. We also need to make sure that we select JSON as our content type and that we choose SmartGroupComputerMembership change as our Webhook event while targeting our smart group for updates.

Results of the flow

  1. In Jamf Pro, a computer is added to a ‘Software Updates Available’ Smart Computer Group
  2. That Smart Computer Group’s membership change data is sent to Microsoft Power Automate
  3. Power Automate uses the data to create a JPAPI call to send the macOS Managed Software Update command
  4. End-user’s computer is updated.

Being able to present this flow to the community at JNUC was awesome, I am honored that I was able to do so. I hope that by reading this post you have been able to come up with your own ideas on how to incorporate other automated workflows into your Jamf Pro to help make your life a bit easier. Thank you for stopping by!

Leave a Reply

Blog at WordPress.com.