MEM Monitoring: Autopilot Profile Assignment Monitoring

As a response on the MEM Monitoring series which I posted in the Modern Endpoint Management LinkedIn group, I was asked if it is also possible to get a notification in case an Autopilot object is not assigned a deployment profile. Yes, this is possible with a pretty simple Logic Apps flow, where we send a notification to a Teams channel for example.

This blog post is part of the MEM (Intune) Monitoring series. An article with a short explanation of every MEM Monitoring flow I shared and links to the related articles can be found here.

So let’s quickly have a look how simple that solution is.

The solution in short

We can query Microsoft Graph using a Logic Apps flow in Azure, which runs on a daily base for the Autopilot objects. We query all objects in our Autopilot tenant and check if the deploymentProfileAssignmentStatus equals notAssigned. If that is true, we send a message to Teams via a Teams Webhook.

Requirements

We don’t have many requirements for this simple flow, we only need an Azure Managed Identity. The managed identity should have enough permissions to query Microsoft Graph for the required information.
The required Graph (application) permission needed is DeviceManagementServiceConfig.Read.All

And if you want to receive the notification in Teams, you must configure a Webhook in the Teams channel.
Another options is to create a report and send it via email.

Setup the Logic App flow

When the Managed identity is created, we can start creating the flow.

Sign in to the Azure portal and open the Logic App service. I created a blank Logic App of type Consumption.



When the flow is created, click on the name of the flow at the top of the screen, open the Identity section, and on the tab User assigned add your Managed Identity.

Open the Overview tab, which shows a few templates, and choose Recurrence.

Change the interval settings to your needs.

Next, we add our first HTTP action.
As Method select GET.
As URI enter:

https://graph.microsoft.com/beta/deviceManagement/windowsAutopilotDeviceIdentities

Choose Add Parameter and select Authentication.
As Authentication type select Managed identity.
Select your Managed identity from the list.
And add https://graph.microsoft.com as Audience.

Next, we need to add a new Parse JSON action. We parse the output of the HTTP action, to be able to use the values later on in the flow.
As Content, we select Body from the Dynamic content list that is from our HTTP action.
As Schema, we can run the current flow and grab the body from the HTTP action and add it via the Use sample payload option. We can also grab the body when we run the same query via Graph Explorer.

This is the schema:

{
    "properties": {
        "@@odata.context": {
            "type": "string"
        },
        "@@odata.count": {
            "type": "integer"
        },
        "value": {
            "items": {
                "properties": {
                    "addressableUserName": {
                        "type": "string"
                    },
                    "azureActiveDirectoryDeviceId": {
                        "type": "string"
                    },
                    "azureAdDeviceId": {
                        "type": "string"
                    },
                    "deploymentProfileAssignedDateTime": {
                        "type": "string"
                    },
                    "deploymentProfileAssignmentDetailedStatus": {
                        "type": "string"
                    },
                    "deploymentProfileAssignmentStatus": {
                        "type": "string"
                    },
                    "deviceAccountPassword": {},
                    "deviceAccountUpn": {
                        "type": "string"
                    },
                    "deviceFriendlyName": {},
                    "displayName": {
                        "type": "string"
                    },
                    "enrollmentState": {
                        "type": "string"
                    },
                    "groupTag": {
                        "type": "string"
                    },
                    "id": {
                        "type": "string"
                    },
                    "lastContactedDateTime": {
                        "type": "string"
                    },
                    "managedDeviceId": {
                        "type": "string"
                    },
                    "manufacturer": {
                        "type": "string"
                    },
                    "model": {
                        "type": "string"
                    },
                    "productKey": {
                        "type": "string"
                    },
                    "purchaseOrderIdentifier": {
                        "type": "string"
                    },
                    "remediationState": {
                        "type": "string"
                    },
                    "remediationStateLastModifiedDateTime": {
                        "type": "string"
                    },
                    "resourceName": {
                        "type": "string"
                    },
                    "serialNumber": {
                        "type": "string"
                    },
                    "skuNumber": {
                        "type": "string"
                    },
                    "systemFamily": {
                        "type": "string"
                    },
                    "userPrincipalName": {
                        "type": "string"
                    }
                },
                "required": [
                    "id",
                    "deploymentProfileAssignmentStatus",
                    "deploymentProfileAssignmentDetailedStatus",
                    "deploymentProfileAssignedDateTime",
                    "groupTag",
                    "purchaseOrderIdentifier",
                    "serialNumber",
                    "productKey",
                    "manufacturer",
                    "model",
                    "enrollmentState",
                    "lastContactedDateTime",
                    "addressableUserName",
                    "userPrincipalName",
                    "resourceName",
                    "skuNumber",
                    "systemFamily",
                    "azureActiveDirectoryDeviceId",
                    "azureAdDeviceId",
                    "managedDeviceId",
                    "displayName",
                    "deviceAccountUpn",
                    "deviceAccountPassword",
                    "deviceFriendlyName",
                    "remediationState",
                    "remediationStateLastModifiedDateTime"
                ],
                "type": "object"
            },
            "type": "array"
        }
    },
    "type": "object"
}

This is the Parse JSON Action.

Now we add a Condition action which is a Control action.
We check if deploymentProfileAssignmentStatus has a value of notAssigned.

in the left box add deploymentProfileAssignmentStatus from the Dynamic content. Choose is equal to from the drop-down list and enter notAssigned to the right box.

By adding the dynamic content, the Condition is added to a For each action.

If the deploymentProfileAssignmentStatus has a value of notAssigned, the condition is true. So under True we add the action to send a notification. We use another HTTP action, to send a message to Teams.

Choose POST as method.
Enter your Teams webhook URL in the URI field. In the Body field we enter the text we like to send to the Teams channel. We can use dynamic content (variables) from the previous Parse JSON action and enter our own text.
Use \n\n in the text to create new lines in the text message, otherwise, the message consists of one long line of text.
And I used ** to get some text in bold.

And this is our flow! Simple, isn’t it?

Your subtitle here

And this is my notification in Teams, which notifies me on the Autopilot object which doesn’t have a deployment profile assigned.

3 Comments

  1. Hello Peter,

    I used the teams body part that you used while assigning the device series that does not assign a profile to the teams channel, but I am getting a 400 error. I checked the Teams uri, it’s correct, but I couldn’t solve the error.

  2. Hello Peter,

    I have created the flow with listed steps. No errors or warning are shown in the Flower checker. However, the specified condition says the Expression Result: false and the HTTP POST webhook reports the following message:
    ActionBranchingConditionNotSatisfied. The execution of template action ‘HTTP_POST_Teams_Webhook’ skipped: the branching condition for this action is not satisfied.

    Any assistance would be greatly appreciated. RWells

Leave a Reply

Your email address will not be published.


*