Export-IntuneApps.psm1
|
function Get-GraphCollection { [CmdletBinding()] param ( [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string]$Uri ) $Items = [System.Collections.Generic.List[object]]::new() $NextUri = $Uri while ($NextUri) { $Page = Invoke-MgGraphRequest -Method GET -Uri $NextUri -ErrorAction Stop foreach ($Item in $Page.value) { $Items.Add($Item) } $NextUri = $Page.'@odata.nextLink' } return $Items.ToArray() } function Export-IntuneApps { <# .SYNOPSIS Exports Intune applications, assignments, and Win32 relationships to CSV. .DESCRIPTION Connects to Microsoft Graph and exports the Intune application inventory to a CSV file. Assignment group IDs are resolved to group names. The output path defaults to IntuneAppsInventory.csv in the current directory, and the delimiter defaults to a semicolon. .PARAMETER Path Destination path for the CSV file. .PARAMETER Delimiter Single-character CSV delimiter. Defaults to a semicolon. .EXAMPLE Export-IntuneApps .EXAMPLE Export-IntuneApps -Path C:\Reports\IntuneApps.csv -Verbose .EXAMPLE Export-IntuneApps -Path C:\Reports\IntuneApps.csv -Delimiter ',' #> [CmdletBinding(SupportsShouldProcess)] param ( [Parameter()] [ValidateNotNullOrEmpty()] [string]$Path = (Join-Path -Path (Get-Location) -ChildPath 'IntuneAppsInventory.csv'), [Parameter()] [char]$Delimiter = ';' ) if (-not $PSCmdlet.ShouldProcess($Path, 'Export Intune application inventory')) { return } if (-not $PSBoundParameters.ContainsKey('InformationAction')) { $InformationPreference = 'Continue' } $Scopes = @( 'DeviceManagementApps.Read.All' 'DeviceManagementConfiguration.Read.All' 'Group.Read.All' ) Connect-MgGraph -Scopes $Scopes -NoWelcome -ErrorAction Stop | Out-Null Write-Information 'Reading groups from Microsoft Graph.' $GroupCache = @{} $Groups = Get-GraphCollection -Uri 'https://graph.microsoft.com/v1.0/groups?$select=id,displayName' foreach ($Group in $Groups) { $GroupCache[$Group.id] = $Group.displayName } Write-Information "Cached $($GroupCache.Count) groups." Write-Information 'Reading applications from Microsoft Graph.' $Apps = Get-GraphCollection -Uri 'https://graph.microsoft.com/beta/deviceAppManagement/mobileApps?$expand=assignments' $Result = [System.Collections.Generic.List[object]]::new() $AppCount = 0 foreach ($App in $Apps) { $AppType = $App.'@odata.type' $AppCount++ $PercentComplete = [int](100 * $AppCount / $Apps.Count) Write-Progress ` -Id 1 ` -Activity 'Exporting Intune applications' ` -Status "Processing app $AppCount of $($Apps.Count): $($App.displayName)" ` -PercentComplete $PercentComplete switch -Wildcard ($AppType) { '*win32LobApp*' { $AppTypeName = 'Win32' } '*windowsStoreApp*' { $AppTypeName = 'Store App' } '*windowsMicrosoftEdgeApp*' { $AppTypeName = 'Edge' } '*webApp*' { $AppTypeName = 'Web Link' } '*officeSuiteApp*' { $AppTypeName = 'Microsoft 3 65 Apps' } default { $AppTypeName = $AppType } } $Relations = @() if ($App.'@odata.type' -like '*win32LobApp*') { try { $Dependencies = Get-GraphCollection -Uri "https://graph.microsoft.com/beta/deviceAppManagement/mobileApps/$($App.id)/relationships" foreach ($Relation in $Dependencies) { $Relations += "$($Relation.targetType): $($Relation.targetDisplayName)" } } catch { Write-Warning "Could not read relationships for app '$($App.displayName)' (ID '$($App.id)'): $_" } } if ($App.PSObject.Properties.Name -contains 'assignments') { $Assignments = @($App.assignments) } else { $Assignments = Get-GraphCollection -Uri "https://graph.microsoft.com/beta/deviceAppManagement/mobileApps/$($App.id)/assignments" } $AssignmentPairs = @() foreach ($Assignment in $Assignments) { if ($null -eq $Assignment) { continue } $GroupName = '' $Intent = $Assignment.intent $GroupId = $Assignment.target.groupId if ($GroupId) { if ($GroupCache.ContainsKey($GroupId)) { $GroupName = $GroupCache[$GroupId] } else { Write-Warning "Group ID '$GroupId' was not found in the group cache." $GroupName = $GroupId } } $AssignmentPairs += "${Intent}: $GroupName" } $ExcelVersion = '="' + ([string]$App.displayVersion).Replace('"', '""') + '"' $Result.Add([PSCustomObject]@{ AppName = $App.displayName Publisher = $App.publisher Version = $ExcelVersion AppType = $AppTypeName CreatedDateTime = $App.createdDateTime LastModifiedDateTime = $App.lastModifiedDateTime Assignments = $AssignmentPairs -join ' | ' Relations = $Relations -join ' | ' AppId = $App.id }) } Write-Progress -Id 1 -Activity 'Exporting Intune applications' -Completed $ResolvedPath = [System.IO.Path]::GetFullPath($Path) $Result | Sort-Object AppName | Export-Csv -LiteralPath $ResolvedPath -NoTypeInformation -Encoding UTF8 -Delimiter $Delimiter -ErrorAction Stop Write-Information "Export created: $ResolvedPath" return $ResolvedPath } Export-ModuleMember -Function Export-IntuneApps |