Close Menu
Peter Klapwijk – In The Cloud 24-7Peter Klapwijk – In The Cloud 24-7
    Facebook X (Twitter) Instagram
    Peter Klapwijk – In The Cloud 24-7Peter Klapwijk – In The Cloud 24-7
    • Home
    • Intune
    • Windows
      • Modern Workplace
    • macOS
    • Android
    • iOS
    • Automation
      • Logic Apps
      • Intune Monitoring
      • GitHub
    • Security
      • Passwordless
      • Security
    • Speaking
    • About me
    Peter Klapwijk – In The Cloud 24-7Peter Klapwijk – In The Cloud 24-7
    Home»Automation»Send a Microsoft Defender Security recommendations report to your users with Logic Apps
    Automation

    Send a Microsoft Defender Security recommendations report to your users with Logic Apps

    Peter KlapwijkBy Peter KlapwijkSeptember 3, 2022Updated:February 14, 202518 Mins Read

    Today’s blog post is about sending a report to end-users with a report of the security recommendations from the Microsoft 365 Defender security portal.

    The thought behind sending such a report to the end-user is that a company has users with local administrator permissions (developers for example) on their (Windows) device and these users install applications that are not maintained by the IT organization. The applications which are deployed by the IT organization are most likely updated by the IT organization on a regular basis. But the applications which are installed by the user themselves, are most likely not (updated by the IT organization). To make these users aware of the outdated applications on their devices, I wanted to send them a report once in a while.

    In the Microsoft 35 Defender portal, we have information available on software that needs an update under the Security recommendations section of every device. If we can grab that information and filter out the software updates (or you might want to send a report with all the recommendations, you don’t filter anything out), we can create a simple report and send that to the owner of the device.

    Let’s have a look at how we can send this report and what the requirements are.

    The solution can be easily deployed with Bicep files, which can be found on my GitHub repo.

    The solution in short

    We can retrieve the devices with their recommendations via the WindowsDefenderATP API. We can query this information using HTTP actions in a Logic Apps flow. We need to retrieve the registered owner of a device (so we know the e-mail address to which we need to send the report), which is possible using Microsoft Graph and also with an HTTP action. The report we can create in this flow is sent via e-mail.

    Requirements

    For this solution, we have some requirements. To retrieve information from the Microsoft Defender and Azure AD via APIs we need to have permission to perform the job. There are different options to authenticate to the security center API and MS Graph and assign permissions, but I prefer an Azure Managed Identity.
    The required Microsoft Graph (Application) permissions we need are:
    Device.Read.All
    User.Read.All

    The required WindowsDefenderATP permissions are:
    SecurityRecommendation.Read.All
    Machine.Read.All

    To send the report via email, we need to have a (shared) mailbox. I used a service account with permission to send an email from a shared mailbox.

    Setup the Logic Apps flow

    When the requirements are met, we can start building our Logic Apps 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.

    The first action we add is an HTTP Action, to query for the machines via the security center API.
    I don’t query all devices available in Defender, I only query the machines of the developers which have a tag assigned (in my example DevComputers). As you can see this is done using the findbytag API.

    As the query by default returns a lot of information that I don’t use, I use a $Select to only select the values I’m interested in.

    Add an HTTP Action.
    Select GET as Method.
    Enter below URI:

    https://api.securitycenter.microsoft.com/api/machines/findbytag?tag=DevComputer&$select=id,computerDnsName,osPlatform,healthStatus,aadDeviceId

    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 Parse JSON action (which is a Data operations 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 a value from our HTTP action.

    As Schema, we can run the current flow (without the Parse JSON action), open the run via runs history, and grab the body from the HTTP action. Then add it via the Use sample payload option to create the schema.

    This is the schema that you use when you use the exact same URI in the HTTP action:

    {
        "properties": {
            "@@odata.context": {
                "type": "string"
            },
            "value": {
                "items": {
                    "properties": {
                        "aadDeviceId": {
                            "type": "string"
                        },
                        "computerDnsName": {
                            "type": "string"
                        },
                        "healthStatus": {
                            "type": "string"
                        },
                        "id": {
                            "type": "string"
                        },
                        "osPlatform": {
                            "type": "string"
                        }
                    },
                    "required": [
                        "id",
                        "computerDnsName",
                        "osPlatform",
                        "healthStatus",
                        "aadDeviceId"
                    ],
                    "type": "object"
                },
                "type": "array"
            }
        },
        "type": "object"
    }

    I only want to send a report to the owner of a device that has an active status in Microsoft Defender. Therefore I use a filter array action, which is also a Data operations action.

    When the health status is equal to active, the data is present as output of the filter array action and inactive machines are filtered out.

    Add the Filter Array action.
    In the left box add healthstatus which is found in the Dynamic content list as a value of the Parse JSON Action. Select is equal to from the drop-down list and enter Active in the right box.

    Now that we have information on our active dev machines, we need to query the API for the recommendations per machine with another HTTP action. As you can see I use $filter to only retrieve recommendations of type Update (remove everything recommendations to query all recommendations).

    Add an HTTP Action.
    Select GET as Method.
    Enter below URI:

    https://api.securitycenter.microsoft.com/api/machines/[ID]/recommendations?$filter=(remediationType%20eq%20'Update')

    Replace [ID] with the ID retrieved from the filter array action. This will add the HTTP Action in a For each action.

    Add the authentication information.

    This time we don’t parse the output from the HTTP action but use a Select (Data operations) action.
    In the From field, we add this expression which retrieves the value data from the HTTP actions body:
    body(‘HTTP_GET_recommendations’)?[‘value’]

    Next enter the information in the Map fields like below.
    Here we map the information from the HTTP action to a value name, which we use later in the flow.

    To map the values, we use an expression on every row:
    item()?[‘relatedComponent’]
    item()?[‘recommendationName’]
    item()?[‘vendor’]
    item()?[‘recommendedVersion’]

    This is our Select action.

    We also query machines that don’t have a recommendation. These machines will return an empty value in the output of the Select recommendation action, on which we can filter out these devices.

    Add a Condition (Control) action.
    In the left box add this expression:
    empty(outputs(‘Select_recommendations’)?[‘body’])

    Select is equal to from the drop-down list and enter false to the right box.

    To retrieve the registered owner of a device, we first query via Microsoft Graph for the Azure AD device object as we have the aadDeviceId retrieved and no usable information on the user.

    Add an HTTP Action.
    Select GET as Method.
    Enter below URI:

    https://graph.microsoft.com/v1.0/devices?$filter=(deviceId%20eq%20'[aadDeviceId]')&$select=id,deviceId,displayName

    Replace [aadDeviceId] which you find as Dynamix content from the filter array action.

    Add the authentication information.

    Parse the output from the HTTP action.

    This is the schema:

    {
        "properties": {
            "@@odata.context": {
                "type": "string"
            },
            "value": {
                "items": {
                    "properties": {
                        "deviceId": {
                            "type": "string"
                        },
                        "displayName": {
                            "type": "string"
                        },
                        "id": {
                            "type": "string"
                        }
                    },
                    "required": [
                        "id",
                        "deviceId",
                        "displayName"
                    ],
                    "type": "object"
                },
                "type": "array"
            }
        },
        "type": "object"
    }

    With this HTTP action, we retrieve the registered owner of the devices.

    Add an HTTP Action.
    Select GET as Method.
    Enter below URI:

    https://graph.microsoft.com/v1.0/devices/[ID]/registeredOwners?$select=id,displayName,userPrincipalName,mail

    Replace [ID] with the ID from the last Parse JSON action. This will add the HTTP action in a For each action.

    Add the authentication information.

    And we use another Parse JSON action, with the below schema:

    {
        "properties": {
            "@@odata.context": {
                "type": "string"
            },
            "value": {
                "items": {
                    "properties": {
                        "@@odata.type": {
                            "type": "string"
                        },
                        "displayName": {
                            "type": "string"
                        },
                        "id": {
                            "type": "string"
                        },
                        "mail": {
                            "type": "string"
                        },
                        "userPrincipalName": {
                            "type": "string"
                        }
                    },
                    "required": [
                        "@@odata.type",
                        "id",
                        "displayName",
                        "userPrincipalName",
                        "mail"
                    ],
                    "type": "object"
                },
                "type": "array"
            }
        },
        "type": "object"
    }

    With a Create CSV table (Data operations) action we can create a simple CSV table with an overview of the retrieved recommendations.

    Add Output, from Select recommendations action in the From field and select Automatic at the Columns drop-down.

    And as last we add an action to send an email with the CSV report.

    you can enter your own information in the Body and subject field. I added displayName from the registered owner and the device to the fields. And I used the mail from the registeredowners action.

    Select Add parameter, to add an attachment.

    As Attachments content add the Output from the Create CSV table action. And enter an attachment name.

    And there he is, our Logic Apps flow:

    End result

    And this is our end result.

    The end user receives an e-mail with a CSV sheet with an overview of the security recommendations.

    In my case, this is an overview of applications that need an update.



    That’s it for this blog post.
    Thanks for reading!

    Logic Apps Microsoft Defender Microsoft Defender for Endpoint Power Automate Security Windows Windows Update
    Share. Facebook Twitter LinkedIn Email WhatsApp
    Peter Klapwijk
    • Website
    • X (Twitter)
    • LinkedIn

    Peter is a Security (Intune) MVP since 2020 and is working as Modern Workplace Engineer at Wortell in The Netherlands. He has more than 15 years of experience in IT, with a strong focus on Microsoft technologies like Microsoft Intune, Windows, and (low-code) automation.

    Related Posts

    MEM Monitoring: Assignment monitoring to keep your tenant cleaned up

    August 24, 2022

    Re-import Autopilot information from Azure Storage on-demand with a Logic Apps flow

    July 9, 2022

    Use Azure Key Vault to secure your Graph API connection in Power Automate

    February 14, 2021
    View 1 Comment

    1 Comment

    1. Jeremy on September 28, 2022 07:51

      Nice! Any idea on how to best do this from a MSP tenant > customer tenants, with the partner API?

      Reply
    Leave A Reply Cancel Reply

    Peter Klapwijk

    Hi! Welcome to my blog post.
    I hope you enjoy reading my articles.

    Hit the About Me button to get in contact with me or leave a comment.

    Awards
    Sponsor
    Latest Posts

    Hide the “Turn on an ad privacy feature” pop-up in Chrome with Microsoft Intune

    April 19, 2025

    How to set Google as default search provider with Microsoft Intune

    April 18, 2025

    Using Windows Autopilot device preparation with Windows 365 Frontline shared cloud PCs

    April 13, 2025

    Using Visual Studio with Microsoft Endpoint Privilege Management, some notes

    April 8, 2025
    follow me
    • Twitter 4.8K
    • LinkedIn 6.1K
    • YouTube
    Tags
    Administrative Templates Android Automation Autopilot Azure Azure AD Browser Conditional Access Edge EMS Exchange Online Feitian FIDO2 Flow Google Chrome Graph Graph API Identity Management Intune Intune Monitoring iOS KIOSK Logic Apps macOS MEM MEMMonitoring Microsoft 365 Microsoft Edge Microsoft Endpoint Manager Modern Workplace Office 365 OneDrive for Business Outlook Passwordless PowerApps Power Automate Security SharePoint Online Teams Windows Windows 10 Windows10 Windows 11 Windows Autopilot Windows Update
    Copy right

    This information is provided “AS IS” with no warranties, confers no rights and is not supported by the authors, or In The Cloud 24-7.

     

    Copyright © 2025 by In The Cloud 24-7/ Peter Klapwijk. All rights reserved, No part of the information on this web site may be reproduced or posted in any form or by any means without the prior written permission of the publisher.

    Shorthand; Don’t pass off my work as yours, it’s not nice.

    Recent Comments
    • Peter Klapwijk on Using Windows Autopilot device preparation with Windows 365 Frontline shared cloud PCs
    • John M on Using Windows Autopilot device preparation with Windows 365 Frontline shared cloud PCs
    • Christoffer Jakobsen on Connect to Azure file shares with Microsoft Entra Private Access
    • Ludo on How to block Bluetooth file transfer with Microsoft Intune
    • RCharles on Automatically configure the time zone (during Autopilot enrollment)
    most popular

    Application installation issues; Download pending

    October 1, 2024

    Restrict which users can logon into a Windows 10 device with Microsoft Intune

    April 11, 2020

    How to change the Windows 11 language with Intune

    November 11, 2022

    Update Microsoft Edge during Windows Autopilot enrollments

    July 9, 2024
    Peter Klapwijk – In The Cloud 24-7
    X (Twitter) LinkedIn YouTube RSS
    © 2025 ThemeSphere. Designed by ThemeSphere.

    Type above and press Enter to search. Press Esc to cancel.

    Manage Cookie Consent
    To provide the best experiences, we use technologies like cookies to store and/or access device information. Consenting to these technologies will allow us to process data such as browsing behavior or unique IDs on this site. Not consenting or withdrawing consent, may adversely affect certain features and functions.
    Functional Always active
    The technical storage or access is strictly necessary for the legitimate purpose of enabling the use of a specific service explicitly requested by the subscriber or user, or for the sole purpose of carrying out the transmission of a communication over an electronic communications network.
    Preferences
    The technical storage or access is necessary for the legitimate purpose of storing preferences that are not requested by the subscriber or user.
    Statistics
    The technical storage or access that is used exclusively for statistical purposes. The technical storage or access that is used exclusively for anonymous statistical purposes. Without a subpoena, voluntary compliance on the part of your Internet Service Provider, or additional records from a third party, information stored or retrieved for this purpose alone cannot usually be used to identify you.
    Marketing
    The technical storage or access is required to create user profiles to send advertising, or to track the user on a website or across several websites for similar marketing purposes.
    Manage options Manage services Manage {vendor_count} vendors Read more about these purposes
    View preferences
    {title} {title} {title}