# Get a better Intune policy report part 2.

In my previous post, I've talked about parsing [Intune MDMDiagReport.html report](https://doitpsway.com/convert-intune-mdmdiagreporthtml-to-powershell-object) and how to convert it to a PowerShell object. There is also the [final post](https://doitpsway.com/get-a-better-intune-policy-report-part-3-final) that merges all this knowledge into the fully-featured solution.

Today I will continue this journey for getting a **better Intune report** by looking at the **MDMDiagReport.xml** file that contains a lot of interesting information that is unfortunately not available in the built-in Intune HTML report. I've created function [ConvertFrom-MDMDiagReportXML](https://github.com/ztrhgf/useful_powershell_functions/blob/master/INTUNE/ConvertFrom-MDMDiagReportXML.ps1) that converts this XML into **PowerShell object** with just important report data or output the results to **nice HTML report**.

I haven't find any documentation describing content of **MDMDiagReport.xml** so I've just reverse engineered it. It means that results can miss or show incorrect information. If this will be your case, please let me know, so I can fix this function.

Btw when I'll talk about built-in Intune HTML report I mean this one

![built-in Intune HTML report](https://cdn.hashnode.com/res/hashnode/image/upload/v1635958932119/5Um9WkNOQ.png align="left")

---

# Table of contents

* [TL;DR](#tldr)
    
* [Meet the ConvertFrom-MDMDiagReportXML function](#meet-the-convertfrom-mdmdiagreportxml-function)
    
* [What is MDMDiagReport.xml and how to get it?](#what-is-mdmdiagreportxml-and-how-to-get-it)
    
* [Interesting XML nodes](#interesting-xml-nodes)
    
    * [MDMEnterpriseDiagnosticsReport.Resources.Enrollment](#mdmenterprisediagnosticsreportresourcesenrollment)
        
    * [MDMEnterpriseDiagnosticsReport.Diagnostics.ErrorLog](#mdmenterprisediagnosticsreportdiagnosticserrorlog)
        
    * [MDMEnterpriseDiagnosticsReport.EnterpriseDesktopAppManagementInfo.MsiInstallation.TargetUser.Package.Details](#mdmenterprisediagnosticsreportenterprisedesktopappmanagementinfomsiinstallationtargetuserpackagedetails)
        
    * [MDMEnterpriseDiagnosticsReport.PolicyManager.ConfigSource](#mdmenterprisediagnosticsreportpolicymanagerconfigsource)
        
    * [MDMEnterpriseDiagnosticsReport.PolicyManager.AreaMetadata](#mdmenterprisediagnosticsreportpolicymanagerareametadata)
        
    * [MDMEnterpriseDiagnosticsReport.PolicyManager.IngestedAdmxPolicyMetadata](#mdmenterprisediagnosticsreportpolicymanageringestedadmxpolicymetadata)
        
* [Converting XML to PowerShell object](#converting-xml-to-powershell-object)
    
* [What are benefits of my report over the built-in one?](#what-are-benefits-of-my-report-over-the-built-in-one)
    
* [How is my HTML report generated](#how-is-my-html-report-generated)
    
* [Summary](#summary)
    
* [Examples](#examples)
    

---

# TL;DR

**Download**, **dot source** and **run** PowerShell function [ConvertFrom-MDMDiagReportXML](https://github.com/ztrhgf/useful_powershell_functions/blob/master/INTUNE/ConvertFrom-MDMDiagReportXML.ps1)

Call `ConvertFrom-MDMDiagReportXML` to get PowerShell object

![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1636357344120/55aQT7FPdq.png align="left")

Call `ConvertFrom-MDMDiagReportXML | Out-GridView` to get nice GUI searchable output

![ConvertFrom-MDMDiagReportXML | Out-GridView result](https://cdn.hashnode.com/res/hashnode/image/upload/v1635961579181/5fssWNIkB.png align="left")

Call `ConvertFrom-MDMDiagReportXML -asHTML -showURLs` to get nice HTML report like

![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1636357165486/fkPgoe4vc.png align="left")

---

# Meet the ConvertFrom-MDMDiagReportXML function

All this blog post is about is my function [ConvertFrom-MDMDiagReportXML](https://github.com/ztrhgf/useful_powershell_functions/blob/master/INTUNE/ConvertFrom-MDMDiagReportXML.ps1). Don't forget it is a function, so you will have to dot source the downloaded script first and then explicitly call it!

Check the [examples](#examples) section for some usage tips.

---

# What is MDMDiagReport.xml and how to get it?

**MDMDiagReport.xml** is XML file containing details about processing of Intune policies.

It can be generated by calling `MdmDiagnosticsTool.exe -out "C:\IntuneReport"` and the result will look like this

![MdmDiagnosticsTool.exe -out "C:ntuneReport" result](https://cdn.hashnode.com/res/hashnode/image/upload/v1635962290858/zspUpZg-E.png align="left")

As you can see besides the MDMDiagReport.xml folder contains also the built-in HTML Intune report and some related event logs.

You don't have to generate it manually, my function will do it for you.

**MDMDiagReport.xml** contains a lot of information about Intune policies processing but (same as original HTML report) not all of them. For example what is missing:

* Applied scripts (scripts and remediation scripts)
    
* Windows app (Win32)
    
* Name of deployed MSI installation
    

These kind of data will be added in my next and hopefully final ultimate `Invoke-IntunePolicyResult` (like `gpresult`) function. 👍

---

# Interesting XML nodes

Now when we have **MDMDiagReport.xml** we need to understand its content hierarchy.

After several days of testing, guessing and testing I've found these important XML nodes:

### MDMEnterpriseDiagnosticsReport.Resources.Enrollment

* All Intune enrollments deployed to this client
    
* What I get there: enrollment ID, scope, setting names
    
    ![all Intune enrollments deployed to this client](https://cdn.hashnode.com/res/hashnode/image/upload/v1635962799424/0GlEU3Qv0.png align="left")
    

### MDMEnterpriseDiagnosticsReport.Diagnostics.ErrorLog

* Deployment errors
    
* What I get there: type of policy, policy name, error code, time of evaluation, ...
    
    ![deployment errors](https://cdn.hashnode.com/res/hashnode/image/upload/v1635963302905/xLl5BlCLt.png align="left")
    

### MDMEnterpriseDiagnosticsReport.EnterpriseDesktopAppManagementInfo.MsiInstallation.TargetUser.Package.Details

* Deployment errors for MSI installations
    
* What I get there: package ID, download URL, used command line, product version, status, assignment type
    
    ![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1636357689787/lP7NTjANZ.png align="left")
    

### MDMEnterpriseDiagnosticsReport.PolicyManager.ConfigSource

* All policies deployed to this client
    
* What I get there: enrollment ID, policy scope, policy area, policy settings
    

I ignore knobs policies because those are just some internal diagnostics data

![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1636357776657/KBctTac9J.png align="left")

### MDMEnterpriseDiagnosticsReport.PolicyManager.AreaMetadata

* Details for policies settings (metadata)
    
* What I get there: policy type, default value, registry key and value it changes
    
    ![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1636357633870/Z_YPly9EM.png align="left")
    

### MDMEnterpriseDiagnosticsReport.PolicyManager.IngestedAdmxPolicyMetadata

* Details for ADMX based? policies settings (metadata)
    
* What I get there: policy type, source Admx file, registry key and value it changes
    
    ![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1636357908753/ebBVgc3ld.png align="left")
    

---

# Converting XML to PowerShell object

To be able to convert XML objects to PowerShell objects I have used function [ConvertFrom-XML](https://github.com/ztrhgf/useful_powershell_functions/blob/master/ConvertFrom-XML.ps1).

90% of function code is based on https://stackoverflow.com/questions/3242995/convert-xml-to-psobject. I just fixed some bugs and make it 30% faster.

---

# What are benefits of my report over the built-in one?

* My report contains **more information** than a built-in one and more importantly shows **just useful information**
    
* Knobs (debug) policies etc are omitted
    
* My report contains:
    
    * policy errors (if any)
        
    * installed MSI applications with version, state etc (name is missing from XML, but will be added in my next version)
        
    * details like what registry key/value is changed, admx template is used, URL to CSP documentation, etc
        
* Function can return PowerShell object (with all benefits it brings) or quite nice HTML report
    

---

# How is my HTML report generated

I've used great PowerShell module [PSWriteHTML](https://github.com/EvotecIT/PSWriteHTML). So I didn't have to write a single line of HTML code by myself :)

Special thanks go to [@evotecpl](https://twitter.com/evotecpl) for his assistance with tuning of this report 👍

Check this nice detail (red background for cells with errors (code different from 0))

![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1636359039350/KiTmrBKDP.png align="left")

---

# Summary

Function [ConvertFrom-MDMDiagReportXML](https://github.com/ztrhgf/useful_powershell_functions/blob/master/INTUNE/ConvertFrom-MDMDiagReportXML.ps1) gets content of \*\*MDMDiagReport.xml \*\*, extracts just important parts and merge them together to one structured PowerShell object or HTML report and returns it. Nothing less nothing more.

For the final solution check my [next post](https://doitpsway.com/get-a-better-intune-policy-report-part-3). There you will see `Get-ClientIntunePolicyResult` function that merges XML data with registry ones which leads to a complete Intune policy report.

---

# Examples

You can use standard PowerShell filtering a.k.a `Where-Object`.

![Where-Object example](https://cdn.hashnode.com/res/hashnode/image/upload/v1636020078788/7XIuodQJS.png align="left")

![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1636019708672/r4FQx-c__X.png align="left")

You can also use `Out-GridView` to get some basic GUI with decent filtering capabilities. The disadvantage of using Out-GridView is the lack of nice readable output for individual setting details.

![Out-GridView example](https://cdn.hashnode.com/res/hashnode/image/upload/v1636019045871/OFY45naBm.png align="left")

![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1636019181442/-mUlbeMH2.png align="left")

Moreover, you can use -PassThru to pass selected object down the pipe for further processing like:

![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1636036729720/sYowdy2dF.png align="left")

And you will get:

![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1636036795655/OS5kvZJgw.png align="left")

Which can be drilled down like:

![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1636036905104/yt7UMkULj.png align="left")

And this is how it looks when you generate HTML report

![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1636359562483/LskCYXhzi9.png align="left")

And now compare it with built-in one :)

![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1636037836095/NK-Sq_WI8.png align="left")
