In this blog post I will describe how you easily can help yourself and your management to know if someone changed configurations or apps in your Microsoft Intune environment.
Many of my customers do have more than one administrator. With a modern way of working “Hybrid work” we sit at different locations, and it is not always that we remember to share what we configured or changed in the system.
The case could also be, that you want to be in control and that no one can do changes without you being aware of it. – Still curious how to do this? Then read along!
I will showcase to you the different ways to achieve this. We will look at Logic Apps and Power Automate and the cost of utilizing the different methods.
Microsoft Intune changes using Logic App

Prerequisites
- Intune diagnostic configured (AuditLogs)
- Azure Subscription
- Log Analytics
Creating your Logic App flow
Start by going to portal.azure.com
Search for Logic apps

Click Add

Add relevant information
- Choose subscription and create a new Resource Group
- Logic App name needs to be unique. A good tip is to add a corporate identifier, but keep it simple.
- Choose your region
- I choose Standard and you can see more on the pricing here
- Review + Create
TIP:
If you use standard you will have a bunch of benefits, but at the same time the price will rise. As a sum up I will show you how much it will cost you using this method. You can also read more here

If you only need to run a small amount of flows then I’d suggest that you use comsumption based instead. It is much cheaper, and I will show you the difference in the summary.
INFO!
Be aware that if you choose the consumption plan, the next couple of pictures will not be the ones you see. – I think you will find your way through anyway, as it is pretty logical.

Create

Click into the new Logic app choose Workflows and click add

Call it whatever you like as long as it makes sense.

Choose Designer

Add Recurrence and set it to a schedule that fit your needs.

Add Run query and visualize results add parameters where you have configured your Log Analytics Workspace
Kudos to Oliver for providing a great example of KQL


IntuneAuditLogs
| where OperationName == "Patch DeviceConfiguration"
or OperationName == "Patch DeviceManagementConfigurationPolicy"
or OperationName == "Patch DeviceManagementIntent"
or OperationName == "Patch DeviceCompliancePolicy"
or OperationName == "Update GroupPolicyConfiguration"
or OperationName == "Create DeviceConfiguration"
or OperationName == "Create DeviceManagementConfigurationPolicy"
or OperationName == "Create DeviceManagementIntent"
or OperationName == "Create DeviceCompliancePolicy"
or OperationName == "Create GroupPolicyConfiguration"
or OperationName == "Delete DeviceConfiguration"
or OperationName == "Delete DeviceManagementConfigurationPolicy"
or OperationName == "Delete DeviceManagementIntent"
or OperationName == "Delete GroupPolicyConfiguration"
or OperationName == "Delete DeviceCompliancePolicy"
or OperationName == "Patch MobileApp"
or OperationName == "Create MobileApp"
or OperationName == "Delete MobileApp"
or OperationName == "Create WindowsFeatureUpdateProfile"
or OperationName == "Patch WindowsFeatureUpdateProfile"
or OperationName == "Delete WindowsFeatureUpdateProfile"
or OperationName == "Create WindowsQualityUpdateProfile"
or OperationName == "Patch WindowsQualityUpdateProfile"
or OperationName == "Delete WindowsQualityUpdateProfile"
| extend PropertiesJson = parse_json(Properties)
| where TimeGenerated > now() - 24hours
| extend ActorJson = parse_json(PropertiesJson.Actor)
| extend Policy = replace_regex(tostring(todynamic(Properties).TargetDisplayNames), @'["\[\]]', "")
| extend ChangedBy = todynamic(Properties).Actor.UPN
| project
TimeGenerated=TimeGenerated,
Policy,
ChangedBy,
Operation=OperationName
| order by TimeGenerated
Again add Run query and visualize results add parameters where you have configured your Log Analytics Workspace. (all settings should be the same as the other object we just configured.)
Kudos to Ugur for providing a great example of KQL

IntuneAuditLogs
| where OperationName == "Patch DeviceConfiguration"
or OperationName == "Patch DeviceManagementConfigurationPolicy"
or OperationName == "Patch DeviceManagementIntent"
or OperationName == "Patch DeviceCompliancePolicy"
or OperationName == "Update GroupPolicyConfiguration"
or OperationName == "Create DeviceConfiguration"
or OperationName == "Create DeviceManagementConfigurationPolicy"
or OperationName == "Create DeviceManagementIntent"
or OperationName == "Create DeviceCompliancePolicy"
or OperationName == "Create GroupPolicyConfiguration"
or OperationName == "Delete DeviceConfiguration"
or OperationName == "Delete DeviceManagementConfigurationPolicy"
or OperationName == "Delete DeviceManagementIntent"
or OperationName == "Delete GroupPolicyConfiguration"
or OperationName == "Delete DeviceCompliancePolicy"
or OperationName == "Patch MobileApp"
or OperationName == "Create MobileApp"
or OperationName == "Delete MobileApp"
or OperationName == "Create WindowsFeatureUpdateProfile"
or OperationName == "Patch WindowsFeatureUpdateProfile"
or OperationName == "Delete WindowsFeatureUpdateProfile"
or OperationName == "Create WindowsQualityUpdateProfile"
or OperationName == "Patch WindowsQualityUpdateProfile"
or OperationName == "Delete WindowsQualityUpdateProfile"
| where TimeGenerated > now() - 24hours
| extend ChangedBy = todynamic(Properties).Actor.UPN
| extend Apps = todynamic(Properties).Actor.ApplicationName
| extend Device = todynamic(Properties).TargetObjectIds
//| extend Policy = todynamic(Properties).TargetDisplayNames
| extend Policy = replace_regex(tostring(todynamic(Properties).TargetDisplayNames), @'["\[\]]', "")
| mv-expand todynamic(Properties).Targets[0].ModifiedProperties
| extend Configuration = todynamic(Properties_Targets_0_ModifiedProperties).Name
| extend ['New Value'] = todynamic(Properties_Targets_0_ModifiedProperties).New
| extend ['Old Value'] = todynamic(Properties_Targets_0_ModifiedProperties).Old
| project TimeGenerated, Policy, Configuration, ['New Value'], ['Old Value'], ChangedBy
| order by TimeGenerated
Add new step and setup Send an email (V2)

TIP:
You can tell the difference on run query and visualize results as when multiple are added, they are numbered. The purple have number 2 where the first (the green) has no number.
You can also rename them if you like, that will make it easier to identify what value you are putting into your body

Click Save

To test your flow right away you can trigger it manually by going to Overview

This is cool. We get an email every day with the changes in it, where we can easily track changes and have no surprises.
Logic app cost per month
A forecast for Logic apps where we use the “Standard” with 1 trigger per day is about 1200dkk pr month.

A forecast for Logic apps where we use the “Consumtion based” with 1 trigger per day is about 2dkk pr month.

Microsoft Intune changes using Power Automate
Prerequisites
- Intune diagnostic configured (AuditLogs)
- Azure Subscription
- Log Analytics
- Power Automate premium connector license (Pricing | Microsoft Power Automate)
Creating your Power Automate flow
Start by going to Power Automate
Click Create and click Scheduled cloud flow

Give it a proper name

Click New Step

Search for Azure monitor logs

We need the one called Run query and visualize results
TIP:
This one requires the Premium license. All other connectors we will be using does not.

Add all the needed informations.
These should be the ones where your log analytics is stored

IntuneAuditLogs
| where OperationName == "Patch DeviceConfiguration"
or OperationName == "Patch DeviceManagementConfigurationPolicy"
or OperationName == "Patch DeviceManagementIntent"
or OperationName == "Patch DeviceCompliancePolicy"
or OperationName == "Update GroupPolicyConfiguration"
or OperationName == "Create DeviceConfiguration"
or OperationName == "Create DeviceManagementConfigurationPolicy"
or OperationName == "Create DeviceManagementIntent"
or OperationName == "Create DeviceCompliancePolicy"
or OperationName == "Create GroupPolicyConfiguration"
or OperationName == "Delete DeviceConfiguration"
or OperationName == "Delete DeviceManagementConfigurationPolicy"
or OperationName == "Delete DeviceManagementIntent"
or OperationName == "Delete GroupPolicyConfiguration"
or OperationName == "Delete DeviceCompliancePolicy"
or OperationName == "Patch MobileApp"
or OperationName == "Create MobileApp"
or OperationName == "Delete MobileApp"
or OperationName == "Create WindowsFeatureUpdateProfile"
or OperationName == "Patch WindowsFeatureUpdateProfile"
or OperationName == "Delete WindowsFeatureUpdateProfile"
or OperationName == "Create WindowsQualityUpdateProfile"
or OperationName == "Patch WindowsQualityUpdateProfile"
or OperationName == "Delete WindowsQualityUpdateProfile"
| extend PropertiesJson = parse_json(Properties)
| where TimeGenerated > now() - 24hours
| extend ActorJson = parse_json(PropertiesJson.Actor)
| extend Policy = replace_regex(tostring(todynamic(Properties).TargetDisplayNames), @'["\[\]]', "")
| extend ChangedBy = todynamic(Properties).Actor.UPN
| project
TimeGenerated=TimeGenerated,
Policy,
ChangedBy,
Operation=OperationName
| order by TimeGenerated
In order to convert the output we need to use Initialize variable

Add your own name to it and make sure you use Type: string

Then you search for Set Variable and in the dropdown you choose what you specified above.
In Value you add the attachment Content from the Run query and visualize results from above

Create yet another Run query and visualize results

IntuneAuditLogs
| where OperationName == "Patch DeviceConfiguration"
or OperationName == "Patch DeviceManagementConfigurationPolicy"
or OperationName == "Patch DeviceManagementIntent"
or OperationName == "Patch DeviceCompliancePolicy"
or OperationName == "Update GroupPolicyConfiguration"
or OperationName == "Create DeviceConfiguration"
or OperationName == "Create DeviceManagementConfigurationPolicy"
or OperationName == "Create DeviceManagementIntent"
or OperationName == "Create DeviceCompliancePolicy"
or OperationName == "Create GroupPolicyConfiguration"
or OperationName == "Delete DeviceConfiguration"
or OperationName == "Delete DeviceManagementConfigurationPolicy"
or OperationName == "Delete DeviceManagementIntent"
or OperationName == "Delete GroupPolicyConfiguration"
or OperationName == "Delete DeviceCompliancePolicy"
or OperationName == "Patch MobileApp"
or OperationName == "Create MobileApp"
or OperationName == "Delete MobileApp"
or OperationName == "Create WindowsFeatureUpdateProfile"
or OperationName == "Patch WindowsFeatureUpdateProfile"
or OperationName == "Delete WindowsFeatureUpdateProfile"
or OperationName == "Create WindowsQualityUpdateProfile"
or OperationName == "Patch WindowsQualityUpdateProfile"
or OperationName == "Delete WindowsQualityUpdateProfile"
| where TimeGenerated > now() - 24hours
| extend ChangedBy = todynamic(Properties).Actor.UPN
| extend Apps = todynamic(Properties).Actor.ApplicationName
| extend Device = todynamic(Properties).TargetObjectIds
//| extend Policy = todynamic(Properties).TargetDisplayNames
| extend Policy = replace_regex(tostring(todynamic(Properties).TargetDisplayNames), @'["\[\]]', "")
| mv-expand todynamic(Properties).Targets[0].ModifiedProperties
| extend Configuration = todynamic(Properties_Targets_0_ModifiedProperties).Name
| extend ['New Value'] = todynamic(Properties_Targets_0_ModifiedProperties).New
| extend ['Old Value'] = todynamic(Properties_Targets_0_ModifiedProperties).Old
| project TimeGenerated, Policy, Configuration, ['New Value'], ['Old Value'], ChangedBy
| order by TimeGenerated
and again we need to change our output using variables


Add information so it looks like you want it to be

Save your flow


Run Flow

And you should see something similar to mine

And shortly after a mail going into your mailbox

Power Automate cost per month
A forecast for Power Automate with 1 trigger per day is about 370dkk pr month. (unfortunately don’t have any graphics for that.)
Summary
There are several ways to automate flows when it comes to Azure and I’ve shown you 2 ways to accomplish a task that can help your daily operations.
It depends on your use which solution will be the cheapest, but if you only need a simple flow with few triggers a month, then I would strongly recommend using consumption based logic app flows.
I hope this blog post was helping you to decide where to add you flow and give you some inspiration to automate stuff using low code.
For more inspiration please have a look at my MVP colleague Peter Klapwijk as he has made a lot of great stuff in this area.