V2 – Get an daily device report via email or teams with logic apps – Step by Step guide

V2 – Get a Daily Device Report via Email or Teams with Logic Apps (Step by Step)

I have already written a blog about how to send a message using Logic Apps to generate a daily device report. After a presentation about automation with Intune and Graph I got good feedback asking if I can do a variant with Co-Managed devices. So I decided to write a V2 of this guide that delivers a complete daily device report and also updates the authentication with a Managed Identity. If you are interested in more blogs around the topic of Logic Apps, let me know and I will be happy to do a deep dive on Logic Apps.

V2 – Get an daily device report via email or teams with logic apps – Step by Step guide
  1. What are the prerequisites?
  2. How to Create a Logic App?
  3. How to grant the necessary permissions to the logic app?
  4. How to create the Logic App?
  5. Send status via Email

Prerequisites for the daily device report

The prerequisites for this daily device report are not really high. You only need permissions to create resources in an Azure subscription and to grant API permissions to a managed identity. Once that is in place, the Logic App can run completely unattended and send your daily device report on a fixed schedule. For more background on the API used here, see the official Microsoft Learn documentation and my earlier device report guide.

How to Create a Logic App?

  • Click + Add
V2 – Get an daily device report via email or teams with logic apps – Step by Step guide
  • Select the Subscription
  • Select or create a Resource Group
  • Enter an unique name of the logic app
  • Select a region
  • Select no for log analytics unless you want to activate this
  • Select Consumption as plan type
  • Select Disabled for Zone redundancy
  • Click Review + create
  • Add tags if you want and click Review + create
  • Click Create

How to grant the necessary permissions to the logic app?

  • First of all you have to make sure that the managed identity of your logic app is activated
V2 – Get an daily device report via email or teams with logic apps – Step by Step guide
  • Open an Azure PowerShell or a PowerShell local on your device
V2 – Get an daily device report via email or teams with logic apps – Step by Step guide
  • Execute the following code (Insert the ID of your managed identity):
Install-Module Microsoft.Graph -Scope CurrentUser

Connect-MgGraph -Scopes Application.Read.All, AppRoleAssignment.ReadWrite.All, RoleManagement.ReadWrite.Directory

$managedIdentityId = "Managed Identity Object ID"
$roleName = "DeviceManagementManagedDevices.Read.All"

$msgraph = Get-MgServicePrincipal -Filter "AppId eq '00000003-0000-0000-c000-000000000000'"
$role = $Msgraph.AppRoles| Where-Object {$_.Value -eq $roleName} 

New-MgServicePrincipalAppRoleAssignment -ServicePrincipalId $managedIdentityId -PrincipalId $managedIdentityId -ResourceId $msgraph.Id -AppRoleId $role.Id
 
Disconnect-MgGraph
  • Do the same also for DeviceManagementConfiguration.Read.All
V2 – Get an daily device report via email or teams with logic apps – Step by Step guide

How to build the daily device report Logic App?

  • We want to build our daily device report flow with a Recurrence trigger. For this select recurrence.
V2 – Get an daily device report via email or teams with logic apps – Step by Step guide
  • Set the schedule to once a day.
  • Add a HTTP Action
  • Fill in the following attributes:
    • Method: GET
    • URI: https://graph.microsoft.com/v1.0/deviceManagement/managedDeviceOverview
  • Click add new Parameter and select Authentication
  • Select Authentication Type as Managed Identity
  • Enter https://graph.microsoft.com as audience
V2 – Get an daily device report via email or teams with logic apps – Step by Step guide
  • Run the first test
V2 – Get an daily device report via email or teams with logic apps – Step by Step guide
  • Check the body if you can see device data
V2 – Get an daily device report via email or teams with logic apps – Step by Step guide
  • Add a Parse JSON Action
  • Select Body as Content and add the following content as Schema:
{
    "type": "object",
    "properties": {
        "@@odata.context": {
            "type": "string"
        },
        "id": {
            "type": "string"
        },
        "enrolledDeviceCount": {
            "type": "integer"
        },
        "mdmEnrolledCount": {
            "type": "integer"
        },
        "dualEnrolledDeviceCount": {
            "type": "integer"
        },
        "deviceOperatingSystemSummary": {
            "type": "object",
            "properties": {
                "androidCount": {
                    "type": "integer"
                },
                "iosCount": {
                    "type": "integer"
                },
                "macOSCount": {
                    "type": "integer"
                },
                "windowsMobileCount": {
                    "type": "integer"
                },
                "windowsCount": {
                    "type": "integer"
                },
                "unknownCount": {
                    "type": "integer"
                },
                "androidDedicatedCount": {
                    "type": "integer"
                },
                "androidDeviceAdminCount": {
                    "type": "integer"
                },
                "androidFullyManagedCount": {
                    "type": "integer"
                },
                "androidWorkProfileCount": {
                    "type": "integer"
                },
                "androidCorporateWorkProfileCount": {
                    "type": "integer"
                },
                "configMgrDeviceCount": {
                    "type": "integer"
                }
            }
        },
        "deviceExchangeAccessStateSummary": {
            "type": "object",
            "properties": {
                "allowedDeviceCount": {
                    "type": "integer"
                },
                "blockedDeviceCount": {
                    "type": "integer"
                },
                "quarantinedDeviceCount": {
                    "type": "integer"
                },
                "unknownDeviceCount": {
                    "type": "integer"
                },
                "unavailableDeviceCount": {
                    "type": "integer"
                }
            }
        }
    }
}
  • To also get the compliance state we do basically the same in a second branch:
V2 – Get an daily device report via email or teams with logic apps – Step by Step guide
V2 – Get an daily device report via email or teams with logic apps – Step by Step guide
  • Add again a Parse JSON block and add the following content
{
    "type": "object",
    "properties": {
        "@@odata.context": {
            "type": "string"
        },
        "inGracePeriodCount": {
            "type": "integer"
        },
        "configManagerCount": {
            "type": "integer"
        },
        "id": {
            "type": "string"
        },
        "unknownDeviceCount": {
            "type": "integer"
        },
        "notApplicableDeviceCount": {
            "type": "integer"
        },
        "compliantDeviceCount": {
            "type": "integer"
        },
        "remediatedDeviceCount": {
            "type": "integer"
        },
        "nonCompliantDeviceCount": {
            "type": "integer"
        },
        "errorDeviceCount": {
            "type": "integer"
        },
        "conflictDeviceCount": {
            "type": "integer"
        }
    }
}

V2 – Get an daily device report via email or teams with logic apps – Step by Step guide

Send status via Email

  • Add an Outlook Send an Email (V2) action
  • Sign in with an account
  • Add the Receiver in the To column
  • Add an Subject
  • If you want to add a date to the subject add the following expression:
string(utcNow('yyyyMMdd'))
  • Add the following in the Body column. (You can modify the text as you want)
Dear MDM Team,

attached your daily report:
- Total devices: @{body('Parse_JSON')?['properties']?['enrolledDeviceCount']}
- Mdm enrolled: @{body('Parse_JSON')?['properties']?['mdmEnrolledCount']}
- Hybrid enrolled: @{body('Parse_JSON')?['properties']?['dualEnrolledDeviceCount']}
- ConfigManDevices: @{body('Parse_JSON')?['deviceOperatingSystemSummary']?['configMgrDeviceCount']}

Per device group:
- Windows: @{body('Parse_JSON')?['properties']?['deviceOperatingSystemSummary']?['properties']?['windowsCount']}
- Android: @{body('Parse_JSON')?['properties']?['deviceOperatingSystemSummary']?['properties']?['androidCount']}
- iOS: @{body('Parse_JSON')?['properties']?['deviceOperatingSystemSummary']?['properties']?['iosCount']}
- MacOS: @{body('Parse_JSON')?['properties']?['deviceOperatingSystemSummary']?['properties']?['macOSCount']}

Compliance:
- Compliant devices: @{body('Parse_JSON_2')?['compliantDeviceCount']}
- Uncompliant devices: @{body('Parse_JSON_2')?['nonCompliantDeviceCount']}

Best regards and have a nice day without troubles
Your logic app
  • Now we can make a test run to check if everything works
V2 – Get an daily device report via email or teams with logic apps – Step by Step guide
V2 – Get an daily device report via email or teams with logic apps – Step by Step guide
  • Check you inbox
V2 – Get an daily device report via email or teams with logic apps – Step by Step guide

Conclusion: your automated daily device report

That is it. With this V2 setup you now have a fully automated daily device report that pulls enrollment and compliance data straight from Microsoft Graph and delivers it to your inbox or Teams every morning. Because the flow uses a Managed Identity, there are no secrets to rotate and it keeps running securely without any maintenance. Feel free to extend the report with extra metrics, swap the Outlook action for a Teams message, or adapt the schedule to your needs. If you found this guide useful, let me know and I will cover more Logic Apps automation scenarios.

9 thoughts on “V2 – Get a Daily Device Report via Email or Teams with Logic Apps (Step by Step)

  1. Hi yannik – it failed on step HTTP2 for me?
    FORBIDDEN:

    {
    “error”: {
    “code”: “Forbidden”,
    “message”: “{\r\n \”_version\”: 3,\r\n \”Message\”: \”Application is not authorized to perform this operation. Application must have one of the following scopes: DeviceManagementConfiguration.Read.All, DeviceManagementConfiguration.ReadWrite.All – Operation ID (for customer support): 00000000-0000-0000-0000-000000000000 – Activity ID: c4e76d81-22fb-40bd-bd50-e4e7ab42092a – Url: https://fef.msua04.manage.microsoft.com/DeviceConfiguration_2305/StatelessDeviceConfigurationFEService/deviceManagement/deviceCompliancePolicyDeviceStateSummary?api-version=5023-03-24\”,\r\n \”CustomApiErrorPhrase\”: \”\”,\r\n \”RetryAfter\”: null,\r\n \”ErrorSourceService\”: \”\”,\r\n \”HttpHeaders\”: \”{}\”\r\n}”,
    “innerError”: {
    “date”: “2023-06-07T11:35:04”,
    “request-id”: “c4e76d81-22fb-40bd-bd50-e4e7ab42092a”,
    “client-request-id”: “c4e76d81-22fb-40bd-bd50-e4e7ab42092a”
    }
    }
    }

  2. Update the send mail V2

    Dear MDM Team,

    attached your daily report:
    – Total devices: @{body(‘Parse_JSON’)?[‘enrolledDeviceCount’]}
    – Mdm enrolled: @{body(‘Parse_JSON’)?[‘mdmEnrolledCount’]}
    – Hybrid enrolled: @{body(‘Parse_JSON’)?[‘dualEnrolledDeviceCount’]}
    – Config Management Devices: @{body(‘Parse_JSON’)?[‘deviceOperatingSystemSummary’]?[‘configMgrDeviceCount’]}

    Per device group:
    – Windows: @{body(‘Parse_JSON’)?[‘deviceOperatingSystemSummary’]?[‘windowsCount’]}
    – Android: @{body(‘Parse_JSON’)?[‘deviceOperatingSystemSummary’]?[‘androidCount’]}
    – iOS: @{body(‘Parse_JSON’)?[‘deviceOperatingSystemSummary’]?[‘iosCount’]}
    – MacOS: @{body(‘Parse_JSON’)?[‘deviceOperatingSystemSummary’]?[‘macOSCount’]}Compliance:- Compliant devices: @{body(‘Parse_JSON_3’)?[‘compliantDeviceCount’]}
    – Uncompliant devices: @{body(‘Parse_JSON_3’)?[‘nonCompliantDeviceCount’]}

    This should work

Comments are closed.