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
- First we need the info about which folder to use from the user.
Param(
[Parameter(Mandatory=$True,Position=1)]
[string]$folder
)
- Second we need to import the nessary modules.
- And third connect to the Microsoft Graph.
Import-Module Microsoft.Graph.Beta.DeviceManagement.Actions
Connect-MgGraph -Scopes 'DeviceManagementConfiguration.Read.All, User.Read.All'
- 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.
# 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.
- This will delete the default Intune folder and the Office file that will be created, and otherwise it will cause problems later on.
Remove-Item -path "$($folder)\iAnnotate for Intune" -confirm:$false
Get-ChildItem -Path $folder -Filter "*]*" | remove-item -confirm:$false
- At the moment, the script will also create some corrupt files without extensions, which need to be deleted.
$files = Get-ChildItem -Path $folder -Filter *.
foreach($file in $files){
Remove-Item -path $file.fullname -confirm:$false
}
- 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.
# 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
- All that remains is to take the rest of the files and transform the data for human reading.
#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
- And the result is a nice readable .csv file, that can be opened in Excel or further processed with other tools.
💾 You can download the complete script in my GitHub Repo. Download