Easily exporting Intune reports using Microsoft Graph

This week a short blog post about Intune reports and more specifically about exporting Intune reports by using Microsoft Graph. Since recently, all reports that are available in the (new) Intune reporting infrastructure are available for export. That export can be achieved from a single top-level export API. Simply use Microsoft Graph API to make the required HTTP call(s). The result of the HTTP call(s) will be a downloadable ZIP-file that contains a CSV-file. That CSV-file contains an export of the latest real-time information and can be imported in EXCEL for some simple data analyses, or in Power BI for more advanced data analyses and visualizations. In this post I’ll show how to use Microsoft Graph to export Intune reports and I’ll show the results of the export.

Export Intune reports

Let’s start with the easiest part, which is knowing the correct Microsoft Graph API endpoint. That’s the endpoint below.

https://graph.microsoft.com/beta/deviceManagement/reports/exportJobs

The more challenging part is the parameters that can be submitted in the request body. Basically there are the following three main parameters that can be submitted in the request body to define the export request:

  • reportName: This is a required parameter (type String) that contains the name of the report that should be exported.
  • filter: This is an optional parameter, for most reports, (type String) that can be used to filter the dataset.
  • select: This is an optional parameter (type String collection) that can be used to select specific columns of the dataset. When nothing is specified, a default set of columns, which for most reports is the entire dataset, is selected.

Note: The documentation about exporting reports provides information about the available reports, the name of the reports, the information that can be used to filter the data and the properties that can be used to select specific columns of the data.

Now when making the request, the reportName parameter must be provided as part of the request body. That parameter contains the name of the report that should be exported. Below is an example of an export request for the Devices report that filters on specific data and only selects specific columns. That example can be used in a HTTP POST method on the request. The HTTP POST method is used to perform an action to export the report. A simple method to perform this action is by using Microsoft Graph Explorer. In Graph Explorer, simply select POST, provide the mentioned endpoint as URL, provide the example below as request body and click Run query.

{
    "reportName": "Devices",
    "filter": "(ManagementAgents eq '2') and (OwnerType eq '1')",
    "select": [
        "DeviceName",
	"DeviceType",
	"Ownership",
        "ManagedBy",
        "managementState",
        "complianceState",
        "OS",
        "OSVersion",
        "LastContact",
        "UPN"
    ],
    "localization": "true",
    "ColumnName": "ui"
}

Note: In most cases I would suggest to not filter the data. I only used a filter to show how it works. A tool like Power BI can be used to actually filter the data and to create some nice data analyses and visualizations. Not filtering the data, when exporting the data, leaves more room for a good interpretation of the data.

After posting the provided HTTP POST method on the request, Microsoft Graph returns a response message. That response message contains the information that was provided in the request and the id and status of the request. Especially the id is important, as that id should be used to follow the status of the request.

{
    "@odata.context": "https://graph.microsoft.com/beta/$metadata#deviceManagement/reports/exportJobs/$entity",
    "id": "Devices_115d909a-7574-4e94-b236-e6e082ab6788",
    "reportName": "Devices",
    "filter": "(ManagementAgents eq '2') and (OwnerType eq '1')",
    "select": [
        "DeviceName",
        "DeviceType",
        "Ownership",
        "ManagedBy",
        "managementState",
        "complianceState",
        "OS",
        "OSVersion",
        "LastContact",
        "UPN"
    ],
    "format": "csv",
    "snapshotId": null,
    "status": "notStarted",
    "url": null,
    "requestDateTime": "2020-10-07T09:42:06.388268Z",
    "expirationDateTime": "0001-01-01T00:00:00Z"
}

To follow the status of the export request, the id can be used to query for an updated status. In Graph Explorer, simply select Get, provide something similar to the example below (just adjust the provided id) as the URL and click Run query.

https://graph.microsoft.com/beta/deviceManagement/reports/exportJobs('Devices_115d909a-7574-4e94-b236-e6e082ab6788')

Once the status of the export request changes to completed, the url in the response will contain a link to a downloadable ZIP-file in a storage blob.

{
    "@odata.context": "https://graph.microsoft.com/beta/$metadata#deviceManagement/reports/exportJobs/$entity",
    "id": "Devices_115d909a-7574-4e94-b236-e6e082ab6788",
    "reportName": "Devices",
    "filter": "(ManagementAgents eq '2') and (OwnerType eq '1')",
    "select": [
        "DeviceName",
        "DeviceType",
        "Ownership",
        "ManagedBy",
        "managementState",
        "complianceState",
        "OS",
        "OSVersion",
        "LastContact",
        "UPN"
    ],
    "format": "csv",
    "snapshotId": null,
    "status": "completed",
    "url": "https://amsub0201repexpstorage.blob.core.windows.net/a3283525-8b8f-428c-a3f6-774ec1f94b6d/Devices_115d909a-7574-4e94-b236-e6e082ab6788.zip?sv=2019-02-02&sr=b&sig=Rm301BTLjYTEmTNl7WHk1UL2bu6TKYIhezlpH8lzveU%3D&skoid=1db6df02-4c8b-4cb3-8394-7ac2390642f8&sktid=72f988bf-86f1-41af-91ab-2d7cd011db47&skt=2020-10-07T09%3A43%3A10Z&ske=2020-10-07T15%3A42%3A52Z&sks=b&skv=2019-02-02&se=2020-10-07T15%3A42%3A52Z&sp=r",
    "requestDateTime": "2020-10-07T09:42:06.388268Z",
    "expirationDateTime": "2020-10-07T15:42:52.0376315Z"
}

Intune reports result

The downloaded ZIP-file has the name of the id of the generated report. That ZIP-file contains a CSV-file and that also has the name of the id of the generated report. After exporting the CSV-file, the data can be imported in anyone’s favorite tool. That can be as simple as EXCEL, or a bit more advanced as Power BI. Especially the latter provides some real (simple) capabilities to transform this data into a report. Below are some examples. Figure 1 provides a quick overview of the exported data in a table format.

Figure 2 also provides a quick overview of a similar exported dataset in a table format, but in this case without the filtering of the data. The main goal is to show my earlier note, which will be even clearer with the next figure.

Figure 3 provides an overview of a visualization of both datasets. The main goal is to show that the non-filtered dataset provides a lot more flexibility when analyzing the data. The totally green pie charts are the filtered dataset and the colored pie charts are the non-filtered datasets.

More information

For more information about exporting Intune reports by using Graph APIs, refer to the following docs:

16 thoughts on “Easily exporting Intune reports using Microsoft Graph”

    • Sorry Jérémy, but I don’t have an example at hand. It shouldn’t be too difficult with the information in this post. Basically just connect to graph and invoke the query.
      Regards, Peter

      Reply
  1. Hi Peter,

    I was wondering, is there something similar for exporting all Azure AD devices including the UPN of the user via Microsoft Graph?

    Best regards,

    Sjoerd

    Reply
  2. How do I use the filter to define only Windows devices? I’m trying this but I’m getting an error “BadRequest”:

    payload = {
    “reportName” : “Devices”,
    “filter” : “(OS eq ‘Windows’)”,
    }

    Reply
  3. Hi Peter,

    I am trying to export the “DeviceInstallStatusByApp” report using Graph API with PowerShell.

    For reference, I followed this article.

    My PowerShell function below has all the details required for the export but still getting the error while sending the first post request with the DeviceInstallStatusByApp reportname field.

    Function Get-ReportJobId {
    [cmdletbinding()]
    param(
    $Appid
    )
    $Apiversion = “beta”
    $Resource = “deviceManagement/reports/exportJobs”

    $URI = “https://graph.microsoft.com/$($Apiversion)/$($Resource)”

    $PostBody = @”

    {
    “reportName” : “DeviceInstallStatusByApp”,
    “filter” : “(ApplicationId eq ‘$($Appid)’)”,
    “select” : [
    “DeviceName”,
    “UserPrincipalName”,
    “Platform”,
    “AppVersion”,
    “AssignmentFilterIdsExist”,
    “LastModifiedDateTime”,
    “AppInstallState”,
    “AppInstallStateDetails”
    ]
    }
    “@

    Invoke-RestMethod -method Post -uri $URI -headers $Headers -Body $PostBody
    }

    Any help would be appreciated.

    Regards,
    Ashish Arya

    Reply
    • This is the error that I get:

      {“error”:{“code”:””,”message”:”The request is invalid.”,”innerError”:{“message”:”exportJob.ReportName : The ReportName field is required.

      Regards,
      Ashish Arya

      Reply

Leave a Reply to Benoit Lambert Cancel reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.