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

I have already written a blog about how to send a message using Logic apps to generate a regular device report. After a presentation about automation with Intune and Graph I got the good feedback if I can do a variant with Co Managed devices. So I decided to write a V2 of this blog and also update the authentication with 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.

  1. What are the prerequisites?
  2. How to Create an 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

What are the prerequisites?

The prerequisites are not really high. You only need permissions to create ressources in a azure subscription and to grant API permissions to an managed identity.

How to Create an Logic App?

  • Click + Add
  • 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
  • Open a Azure PowerShell or a PowerShell local on your device
  • 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

How to create the Logic App?

  • We want to build out flow with an Recurrence trigger. For this select recurrence.
  • Set the schedule to once a day.
  • Click add new Parameter and select Authentication
  • Select Authentication Type as Managed Identity
  • Enter https://graph.microsoft.com as audience
  • Run the first test
  • Check the body if you can see device data
  • 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:
  • Add again an 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"
        }
    }
}

Send status via Email

  • Add an Outlook Send an Email (V2) action
  • Sing in with an account
  • Add the Reciver in the To column
  • Add an Subject
  • If you want to add an 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 an test run to check if everything works
  • Check you inbox

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

  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”
    }
    }
    }

    Like

    • Hi Yannik,
      It is working – but the Data is wrong ( no data at all)
      What am I doing wrong?

      Like

    • The concept works – I get a email. So we care good. Apart from that teh Data is 0 😦
      we constantly enroll devices….
      What am I doing wrong?

      Below is your daily Device report:

      Total devices:
      Mdm enrolled:
      Hybrid enrolled:
      ConfigManDevices: 0

      Per device group:

      Windows:
      Android:
      iOS:
      MacOS:

      Compliance:

      Compliant devices:
      Uncompliant devices:

      Like

  2. Cool concept, Jannik, but unfortunately I’m being stopped by these pay-walls. You should do one with pure MSGraph calls and PowerShell for us poor folks. 🙂

    Like

  3. same as Daniel concept works, Beta data will be retrieved:

    Daily status rapport:
    – Total devices:
    – Mdm enrolled:
    – Hybrid enrolled:
    – ConfigManDevices: 0

    Per categorie:
    – Windows:
    – Android:
    – iOS:
    – MacOS:

    Compliance:
    – Compliant devices: 13
    – Uncompliant devices: 2

    Like

  4. 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 Managment 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

    Like

Comments are closed.