Public/Export-M365IntuneAppReport.ps1
|
function Export-M365IntuneAppReport { <# .SYNOPSIS Generates an interactive HTML software inventory report from Intune detected apps. .DESCRIPTION Builds on Get-M365IntuneApp and renders a self-contained HTML page: a KPI overview (apps, installs, unique titles, widely deployed) and a searchable, filterable, sortable table of software with version, publisher, platform and device count. Read-only. .PARAMETER Path Target path of the HTML file. Default: .\IntuneApp-Report.html .PARAMETER MinDevices Only include apps installed on at least this many devices. Default: 1. .PARAMETER WideThreshold Device count from which an app counts as "widely deployed". Default: 10. .PARAMETER BrandName Branding. For CloudNest365: -BrandName 'CloudNest365' .PARAMETER PassThru Also emit the app objects on the pipeline. .PARAMETER NoOpen Do not open the report automatically. .EXAMPLE Export-M365IntuneAppReport -MinDevices 3 -BrandName 'CloudNest365' #> [CmdletBinding()] [OutputType([pscustomobject])] param( [string]$Path = (Join-Path (Get-Location) 'IntuneApp-Report.html'), [int]$MinDevices = 1, [int]$WideThreshold = 10, [string]$BrandName = 'TenantToolbox', [string]$BrandTagline = 'M365 Tenant Administration', [switch]$Csv, [switch]$Excel, [string]$DataPath, [switch]$NoHtml, [switch]$PassThru, [switch]$NoOpen ) Assert-TTGraph $data = @(Get-M365IntuneApp -MinDevices $MinDevices) function Get-Os { param($os) $o = [string]$os if ($o -match 'windows') { 'windows' } elseif ($o -match 'ios|ipad') { 'ios' } elseif ($o -match 'android') { 'android' } elseif ($o -match 'mac') { 'macos' } else { 'other' } } # KPIs $total = $data.Count $installs = ($data | Measure-Object Devices -Sum).Sum $titles = @($data | Select-Object -ExpandProperty App -Unique).Count $wide = @($data | Where-Object { $_.Devices -ge $WideThreshold }).Count $genAt = Get-Date -Format 'yyyy-MM-dd HH:mm' $tenant = (Get-MgContext).TenantId $rows = foreach ($a in ($data | Sort-Object Devices -Descending)) { $osKey = Get-Os $a.Platform $fWide = if ($a.Devices -ge $WideThreshold) { '1' } else { '0' } $devSort = ('{0:D7}' -f [int]$a.Devices) $searchAttr = TTEnc ("$($a.App) $($a.Version) $($a.Publisher)".ToLower()) $nameAttr = TTEnc ([string]$a.App).ToLower() @" <tr class="item" data-f-wide="$fWide" data-f-$osKey="1" data-name="$nameAttr" data-s-devices="$devSort" data-search="$searchAttr"> <td><div class="u"><b>$(TTEnc $a.App)</b><span class="upn">$(if ($a.Publisher) { TTEnc $a.Publisher } else { '' })</span></div></td> <td><span class="chip">$(if ($a.Version) { TTEnc $a.Version } else { '–' })</span></td> <td>$(if ($a.Platform) { TTEnc $a.Platform } else { '<span class="muted">–</span>' })</td> <td data-s-devices="$devSort"><b>$($a.Devices)</b></td> <td>$(if ($null -ne $a.SizeMB) { "$($a.SizeMB) MB" } else { '<span class="muted">–</span>' })</td> </tr> "@ } $kpiHtml = New-TTKpis @( @{ n = $total; l = 'App versions'; filter = 'all' } @{ n = $titles; l = 'Unique titles'; kind = 'info' } @{ n = $installs; l = 'Total installs'; kind = 'ok' } @{ n = $wide; l = "On $WideThreshold+ devices"; kind = 'warn'; filter = 'wide' } ) $toolbar = New-TTToolbar -SearchPlaceholder 'Search app, version or publisher ...' -Filters @( @{ label = 'All'; key = 'all' }, @{ label = "On $WideThreshold+ devices"; key = 'wide' }, @{ label = 'Windows'; key = 'windows' }, @{ label = 'iOS'; key = 'ios' }, @{ label = 'Android'; key = 'android' }, @{ label = 'macOS'; key = 'macos' } ) $body = @" <div class="panel"> <table class="tbl"> <thead><tr><th data-sort="name">Application</th><th>Version</th><th>Platform</th><th data-sort="devices">Devices</th><th>Size</th></tr></thead> <tbody> $($rows -join "`n") </tbody> </table> <div class="empty" id="empty">No application matches the filters.</div> </div> "@ $sub = "Tenant $tenant · generated $genAt · $total app versions on $installs installs" $html = New-TTHtmlPage -Title 'Intune Software Inventory' -Heading 'Intune Software Inventory' -Sub $sub ` -BrandName $BrandName -BrandTagline $BrandTagline -KpiHtml $kpiHtml -ToolbarHtml $toolbar -BodyHtml $body Write-TTLog -Level INFO -Message "Intune app report created: $Path ($total app versions, $titles titles, $installs installs)." $flat = $data | Select-Object App, Version, Publisher, Platform, Devices, SizeMB Complete-TTReport -Html $html -Path $Path -Data $flat -Csv:$Csv -Excel:$Excel -DataPath $DataPath -NoHtml:$NoHtml -NoOpen:$NoOpen -Kind 'Intune-App-Report' if ($PassThru) { $data } } |