Public/Entra/Applications/Get-MgApplicationAssignment.ps1
|
<#
.SYNOPSIS Retrieves all Entra ID applications and their assignment types. .DESCRIPTION This function returns a list of all Entra ID applications with their assignment information, identifying whether they are assigned to all users or have specific assignments. .EXAMPLE $apps = Get-MgApplicationAssignment .EXAMPLE $apps = Get-MgApplicationAssignment -ApplicationId "xxx", "yyy" .EXAMPLE $apps = Get-MgApplicationAssignment -OnlyAssignedToAllUsers .EXAMPLE Get-MgApplicationAssignment -ExportToExcel Gets all applications and exports them to an Excel file #> function Get-MgApplicationAssignment { param( [Parameter(Mandatory = $false)] [String[]]$ApplicationId, [Parameter(Mandatory = $false)] [switch]$OnlyAssignedToAllUsers, [Parameter(Mandatory = $false)] [switch]$ExportToExcel ) # Get all service principals (enterprise applications) if ($ApplicationId) { $servicePrincipals = @() foreach ($appId in $ApplicationId) { try { $sp = Get-MgServicePrincipal -Filter "AppId eq '$appId'" -ErrorAction Stop if ($sp) { $servicePrincipals += $sp } } catch { Write-Warning "Could not find application with ID: $appId" } } } else { $servicePrincipals = Get-MgServicePrincipal -All } # Initialize results array [System.Collections.Generic.List[PSCustomObject]]$applicationAssignmentsArray = @() Write-Host "[$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')] Début de l'analyse de $($servicePrincipals.Count) applications..." -ForegroundColor Cyan $counter = 0 foreach ($sp in $servicePrincipals) { $counter++ Write-Host "[$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')] [$counter/$($servicePrincipals.Count)] Analyse de l'application: $($sp.DisplayName)" -ForegroundColor Cyan # Get app role assignments for this service principal $appRoleAssignments = Get-MgServicePrincipalAppRoleAssignedTo -ServicePrincipalId $sp.Id if ($appRoleAssignments.Count -gt 0) { # Process each assignment individually foreach ($assignment in $appRoleAssignments) { # Initialize assignment properties in logical order for readability $assignmentProps = [ordered]@{ # Application info (most important first) ApplicationName = $sp.DisplayName AssignmentType = '' PrincipalType = '' IsRoleAssignableGroup = $null # Principal details (User, Group, or Service Principal) UserName = $null UserPrincipalName = $null GroupName = $null GroupType = $null ServicePrincipalName = $null ServicePrincipalType = $null PrincipalDisplayName = $null # Role and permission details AppRoleValue = ($sp.AppRoles | Where-Object { $_.Id -eq $assignment.AppRoleId }).Value AppRoleId = $assignment.AppRoleId AppRoleAssignmentRequired = $sp.AppRoleAssignmentRequired # Technical IDs (less important, at the end) ApplicationId = $sp.AppId ServicePrincipalId = $sp.Id UserId = $null GroupId = $null AssignedServicePrincipalId = $null PrincipalId = $null IsAssignableToRole = $null ServicePrincipalAppId = $null # Metadata (at the end) ApplicationPublisher = $sp.PublisherName CreatedDate = $assignment.CreatedDateTime } if ($assignment.PrincipalType -eq 'User') { $assignmentProps.AssignmentType = 'User Assignment' $assignmentProps.PrincipalType = 'User' try { $user = Get-MgUser -UserId $assignment.PrincipalId -ErrorAction SilentlyContinue if ($user) { Write-Host "[$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')] -> Utilisateur trouvé: $($user.DisplayName)" -ForegroundColor Green $assignmentProps.UserName = $user.DisplayName $assignmentProps.UserPrincipalName = $user.UserPrincipalName $assignmentProps.UserId = $user.Id } else { $assignmentProps.AssignmentType = 'User Assignment (Not Found)' $assignmentProps.UserName = "User ID: $($assignment.PrincipalId)" $assignmentProps.UserPrincipalName = 'Unknown' $assignmentProps.UserId = $assignment.PrincipalId } } catch { Write-Host "[$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')] -> Erreur lors de la récupération de l'utilisateur $($assignment.PrincipalId): $($_.Exception.Message)" -ForegroundColor Red $assignmentProps.AssignmentType = 'User Assignment (Error)' $assignmentProps.UserName = "User ID: $($assignment.PrincipalId)" $assignmentProps.UserPrincipalName = 'Unknown' $assignmentProps.UserId = $assignment.PrincipalId } } elseif ($assignment.PrincipalType -eq 'Group') { $assignmentProps.AssignmentType = 'Group Assignment' $assignmentProps.PrincipalType = 'Group' try { $group = Get-MgGroup -GroupId $assignment.PrincipalId -ErrorAction SilentlyContinue if ($group) { $protectedStatus = if ($null -ne $group.IsAssignableToRole) { $group.IsAssignableToRole } else { "N/A" } Write-Host "[$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')] -> Groupe trouvé: $($group.DisplayName) (Protected: $protectedStatus)" -ForegroundColor Green $assignmentProps.GroupName = $group.DisplayName $assignmentProps.GroupId = $group.Id $assignmentProps.GroupType = $group.GroupTypes -join ',' $assignmentProps.IsAssignableToRole = $group.IsAssignableToRole $assignmentProps.IsRoleAssignableGroup = $group.IsAssignableToRole } else { $assignmentProps.AssignmentType = 'Group Assignment (Not Found)' $assignmentProps.GroupName = "Group ID: $($assignment.PrincipalId)" $assignmentProps.GroupId = $assignment.PrincipalId $assignmentProps.GroupType = 'Unknown' $assignmentProps.IsAssignableToRole = $null $assignmentProps.IsRoleAssignableGroup = $null } } catch { Write-Host "[$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')] -> Erreur lors de la récupération du groupe $($assignment.PrincipalId): $($_.Exception.Message)" -ForegroundColor Red $assignmentProps.AssignmentType = 'Group Assignment (Error)' $assignmentProps.GroupName = "Group ID: $($assignment.PrincipalId)" $assignmentProps.GroupId = $assignment.PrincipalId $assignmentProps.GroupType = 'Unknown' $assignmentProps.IsAssignableToRole = $null $assignmentProps.IsRoleAssignableGroup = $null } } elseif ($assignment.PrincipalType -eq 'ServicePrincipal') { $assignmentProps.AssignmentType = 'Service Principal Assignment' $assignmentProps.PrincipalType = 'ServicePrincipal' try { $servicePrincipal = Get-MgServicePrincipal -ServicePrincipalId $assignment.PrincipalId -ErrorAction SilentlyContinue if ($servicePrincipal) { Write-Host "[$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')] -> Service Principal trouvé: $($servicePrincipal.DisplayName)" -ForegroundColor Magenta $assignmentProps.ServicePrincipalName = $servicePrincipal.DisplayName $assignmentProps.ServicePrincipalAppId = $servicePrincipal.AppId $assignmentProps.ServicePrincipalType = $servicePrincipal.ServicePrincipalType $assignmentProps.AssignedServicePrincipalId = $servicePrincipal.Id } else { $assignmentProps.AssignmentType = 'Service Principal Assignment (Not Found)' $assignmentProps.ServicePrincipalName = "Service Principal ID: $($assignment.PrincipalId)" $assignmentProps.AssignedServicePrincipalId = $assignment.PrincipalId $assignmentProps.ServicePrincipalAppId = 'Unknown' $assignmentProps.ServicePrincipalType = 'Unknown' } } catch { Write-Host "[$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')] -> Erreur lors de la récupération du Service Principal $($assignment.PrincipalId): $($_.Exception.Message)" -ForegroundColor Red $assignmentProps.AssignmentType = 'Service Principal Assignment (Error)' $assignmentProps.ServicePrincipalName = "Service Principal ID: $($assignment.PrincipalId)" $assignmentProps.AssignedServicePrincipalId = $assignment.PrincipalId $assignmentProps.ServicePrincipalAppId = 'Unknown' $assignmentProps.ServicePrincipalType = 'Unknown' } } else { # Handle unknown/unsupported principal types $assignmentProps.AssignmentType = "$($assignment.PrincipalType) Assignment" $assignmentProps.PrincipalType = $assignment.PrincipalType $assignmentProps.PrincipalId = $assignment.PrincipalId $assignmentProps.PrincipalDisplayName = "Unknown $($assignment.PrincipalType)" Write-Host "[$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')] -> Type de principal non géré: $($assignment.PrincipalType) (ID: $($assignment.PrincipalId))" -ForegroundColor DarkYellow } # Create and add the assignment object $object = [PSCustomObject]$assignmentProps $applicationAssignmentsArray.Add($object) } } else { # No assignments found - create one entry using the same complete structure $assignmentProps = [ordered]@{ # Application info (most important first) ApplicationName = $sp.DisplayName AssignmentType = '' PrincipalType = '' IsRoleAssignableGroup = $null # Principal details (User, Group, or Service Principal) UserName = $null UserPrincipalName = $null GroupName = $null GroupType = $null ServicePrincipalName = $null ServicePrincipalType = $null PrincipalDisplayName = $null # Role and permission details AppRoleValue = $null AppRoleId = $null AppRoleAssignmentRequired = $sp.AppRoleAssignmentRequired # Technical IDs (less important, at the end) ApplicationId = $sp.AppId ServicePrincipalId = $sp.Id UserId = $null GroupId = $null AssignedServicePrincipalId = $null PrincipalId = $null IsAssignableToRole = $null ServicePrincipalAppId = $null # Metadata (at the end) ApplicationPublisher = $sp.PublisherName CreatedDate = $sp.CreatedDateTime } if ($sp.AppRoleAssignmentRequired -eq $false) { $assignmentProps.AssignmentType = 'All Users (No Assignment Required)' $assignmentProps.PrincipalType = 'All Users' Write-Host "[$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')] -> Application disponible pour tous les utilisateurs (aucune assignation requise)" -ForegroundColor Yellow } else { $assignmentProps.AssignmentType = 'Not Assigned' $assignmentProps.PrincipalType = 'None' Write-Host "[$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')] -> Aucune assignation trouvée" -ForegroundColor Gray } # Create and add the no-assignment object $object = [PSCustomObject]$assignmentProps $applicationAssignmentsArray.Add($object) } } Write-Host "[$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')] Analyse terminée. Total d'éléments trouvés: $($applicationAssignmentsArray.Count)" -ForegroundColor Cyan # Apply filtering if requested if ($OnlyAssignedToAllUsers.IsPresent) { $beforeCount = $applicationAssignmentsArray.Count $applicationAssignmentsArray = $applicationAssignmentsArray | Where-Object { $_.AssignmentType -eq 'All Users (No Assignment Required)' } Write-Host "[$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')] Filtrage appliqué (OnlyAssignedToAllUsers): $($applicationAssignmentsArray.Count)/$beforeCount éléments conservés" -ForegroundColor Cyan } if ($ExportToExcel.IsPresent) { $now = Get-Date -Format 'yyyy-MM-dd_HHmmss' $excelFilePath = "$($env:userprofile)\$now-MgApplicationAssignment.xlsx" Write-Host -ForegroundColor Cyan "Exporting application assignments to Excel file: $excelFilePath" $applicationAssignmentsArray | Export-Excel -Path $excelFilePath -AutoSize -AutoFilter -WorksheetName 'EntraApplicationAssignments' Write-Host -ForegroundColor Green 'Export completed successfully!' } else { return $applicationAssignmentsArray } } |