Skip to content

Intune - App User install status report

Introduction

Managing application installations is crucial for any organization. Microsoft Intune, combined with Microsoft Graph, offers powerful tools to monitor and report on app installations. However, Intune provides these reports per app, requiring you to click into each one individually. In this article, we'll show you how to extract the Intune App user install status data using Microsoft Graph and compile it into an Excel file for a complete overview. This approach will help you track deployments across your organization.

Creating the script

Getting the information

  1. First we need the info about which folder to use from the user.
powershell
Param(
  [Parameter(Mandatory=$True,Position=1)]
  [string]$folder
)
  1. Second we need to import the nessary modules.
  2. And third connect to the Microsoft Graph.
powershell
Import-Module Microsoft.Graph.Beta.DeviceManagement.Actions
Connect-MgGraph -Scopes 'DeviceManagementConfiguration.Read.All, User.Read.All'
  1. Next we download the installation information for each app.

TIP

The command 'Get-MgBetaDeviceManagementReportUserInstallStatusReport' is still in beta and has a few problems at the moment.
Thats why we need to download the data in chunks of 50.

powershell
# Get all apps to iterate through them
$apps = Get-MgDeviceAppManagementMobileApp | select displayname, id
foreach ($app in $apps) {
    # Output the first file which will have the first 50 entries, but also a total row count.
    $outfile = "$($folder)\$($app.DisplayName)_1.json"
    Get-MgBetaDeviceManagementReportUserInstallStatusReport -Filter "(ApplicationId eq '$($app.id)')" -outfile $outfile  -top 50
    $count = 50
    $iteration = 1
    # Read the content of the JSON file and convert it to a PowerShell object
    $Json = Get-Content -Path $outfile | ConvertFrom-Json
    # Get the same app again and again with a different starting point, until we have all the data.
    if ($json.totalrowcount -gt $count){
        Do {
            $iteration = $iteration + 1
            Get-MgBetaDeviceManagementReportUserInstallStatusReport -Filter "(ApplicationId eq '$($app.id)')" -outfile "$($folder)\$($app.DisplayName)_$($iteration).json" -skip $count -top 50
            $count = $count + 50
        } until ($count -gt $json.totalrowcount)
    }
}

Deleting superfluous files

INFO

The script puts out a lot of files for intune apps that you didnt nessaryly use.
I can`t say if this is expected behaviour or a sideproduct of the beta module.
But we need to clean them up first before we can procede.

  1. This will delete the default Intune folder and the Office file that will be created, and otherwise it will cause problems later on.
powershell
Remove-Item -path "$($folder)\iAnnotate for Intune" -confirm:$false
Get-ChildItem -Path $folder -Filter "*]*" | remove-item -confirm:$false
  1. At the moment, the script will also create some corrupt files without extensions, which need to be deleted.
powershell
$files = Get-ChildItem -Path $folder -Filter *.
foreach($file in $files){
  Remove-Item -path $file.fullname -confirm:$false
}
  1. Then we need to delete the application files that are empty (no installations or uninstallations).

WARNING

The provided data is in JSON format, but has an odd schema. So we need to take it apart and make it readable for our script.

powershell
# Get all files in the folder ending with .json and iterate through them
$files = Get-ChildItem -Path $folder -Filter *.json
foreach($file in $files){
  # Read the content of the JSON file and convert it to a PowerShell object
  $jsondata = get-content -path $file.fullname | ConvertFrom-Json
  # Create an array of objects with properties matching the schema
  $data = foreach ($row in $jsonData.Values) {
  $obj = New-Object PSObject
      for ($i = 0; $i -lt $jsonData.Schema.Count; $i++) {
          $obj | Add-Member -MemberType NoteProperty -Name $jsonData.Schema[$i].Column -Value $row[$i]
      }
  $obj
  }
  # Delete the file if there is no user entry in the file
  if(!($data)){
  Remove-Item -path $file.fullname -confirm:$false
  }
}

Transforming the data

  1. All that remains is to take the rest of the files and transform the data for human reading.
powershell
#creating the array for the .csv file
$csv = @()
# Get all files in the folder ending with .json and iterate through them
$files = Get-ChildItem -Path $folder -Filter *.json
foreach($file in $files){
    # Saves the app name (aka the file name) to a variable
    $app = $file.name
    $app = $app -replace "_1.json",""
    # Read the content of the JSON file and convert it to a PowerShell object
    $jsondata = get-content -path $file.fullname | ConvertFrom-Json
    # Create an array of objects with properties matching the schema
    $data = foreach ($row in $jsonData.Values) {
        $obj = New-Object PSObject
        for ($i = 0; $i -lt $jsonData.Schema.Count; $i++) {
            $obj | Add-Member -MemberType NoteProperty -Name $jsonData.Schema[$i].Column -Value $row[$i]
        }
        # Adds the name of the app to the object
        $obj | Add-Member -MemberType NoteProperty -Name "App" -Value $app
        $obj
        # Loop checks if user still exists in EntraID and is enabled
        if (get-mguser -filter "userprincipalname eq '$($obj.UserPrincipalName)' and accountEnabled eq true") {
        # Info is added tot the .csv array
            $csv += , $obj
        }
  }
}
# Exports the array to a CSV file
# array values provided by Intune: userprincipalname, UserId, ApplicationId, UserName, UserPrincipalName, InstalledCount, FailedCount, PendingInstallCount, NotApplicableCount, NotInstalledCount
$csv | Export-Csv -Path "$($folder)\report.csv" -NoTypeInformation -Delimiter ";" -Encoding unicode
  1. And the result is a nice readable .csv file, that can be opened in Excel or further processed with other tools.
drawing

💾 You can download the complete script in my GitHub Repo. Download