Public/Get-ArgusRequiredPermission.ps1
|
function Get-ArgusRequiredPermission { <# .SYNOPSIS Lists the permissions ARGUS needs, per check or aggregated. .DESCRIPTION Returns the Microsoft Graph permissions, Entra ID directory roles and Exchange Online permission required by the selected checks. A check needs its own Requires.GraphScopes plus the permissions of every shared data set it uses (Requires.DataSets). By default one object per check is returned. Use -Aggregate to get the de-duplicated union plus the core permissions ARGUS always needs (tenant details, licence detection, report settings, the signed-in user's roles): this is the list Connect-Argus requests at sign-in. Use -AsAppPermission for unattended runs: the Graph permission names are the same, granted as application permissions (app roles), and Exchange uses Exchange.ManageAsApp plus an Entra role. With delegated (interactive) sign-in, a permission is only effective together with a directory role of the signed-in user: DirectoryRoles lists the least-privileged built-in roles that can read the data. The recommended roles for running ARGUS are Global Reader and Reports Reader. All permissions are read-only. .PARAMETER Area Restrict the list to checks of these areas. .PARAMETER Id Restrict the list to these check IDs. .PARAMETER Aggregate Return a single de-duplicated object for all selected checks, including the core permissions. .PARAMETER AsAppPermission Describe application permissions (app-only) rather than delegated scopes. .EXAMPLE Get-ArgusRequiredPermission Lists the delegated Graph scopes and roles required by each check. .EXAMPLE Get-ArgusRequiredPermission -Aggregate Lists every delegated scope Connect-Argus requests at sign-in. .EXAMPLE Get-ArgusRequiredPermission -Aggregate -AsAppPermission Lists the application permissions to grant to an app registration for unattended runs. .OUTPUTS PSCustomObject with CheckId, Title, PermissionType, Services, GraphPermissions, DirectoryRoles, ExchangePermission and Licenses. .LINK Connect-Argus .LINK Test-ArgusPrerequisite #> [CmdletBinding()] [OutputType([pscustomobject])] param( [Parameter()] [ValidateSet('EntraID', 'Applications', 'Licensing', 'GroupsTeams', 'SharePoint', 'Exchange', 'Copilot')] [string[]] $Area, [Parameter()] [ValidatePattern('^ARG\.[A-Z]{3}\.\d{3}$')] [string[]] $Id, [Parameter()] [switch] $Aggregate, [Parameter()] [switch] $AsAppPermission ) $dataSets = @{} foreach ($definition in Get-ArgusDataSetDefinition) { $dataSets[$definition.Name] = $definition } $permissionType = if ($AsAppPermission) { 'Application' } else { 'Delegated' } $exchangePermission = if ($AsAppPermission) { 'Exchange.ManageAsApp (Office 365 Exchange Online API) and the Entra role Global Reader for the app' } else { 'Entra role Global Reader, or Exchange role group View-Only Organization Management' } $checks = @($script:ArgusBuiltInChecks | Where-Object { (-not $Area -or $_.Area -in $Area) -and (-not $Id -or $_.Id -in $Id) }) $describe = { param([object[]] $Selected, [string] $CheckId, [string] $Title, [string[]] $Extra) $graph = [System.Collections.Generic.SortedSet[string]]::new([System.StringComparer]::OrdinalIgnoreCase) $roles = [System.Collections.Generic.SortedSet[string]]::new([System.StringComparer]::OrdinalIgnoreCase) $services = [System.Collections.Generic.SortedSet[string]]::new([System.StringComparer]::OrdinalIgnoreCase) $licenses = [System.Collections.Generic.SortedSet[string]]::new([System.StringComparer]::OrdinalIgnoreCase) foreach ($permission in $Extra) { $null = $graph.Add($permission) } foreach ($check in $Selected) { foreach ($scope in $check.Requires.GraphScopes) { $null = $graph.Add($scope) } foreach ($service in $check.Requires.Services) { $null = $services.Add($service) } foreach ($license in $check.Requires.Licenses) { $null = $licenses.Add($license) } foreach ($name in @($check.Requires.DataSets) + @($check.Requires.OptionalDataSets)) { if (-not $dataSets.ContainsKey($name)) { continue } $dataSet = $dataSets[$name] $null = $services.Add($dataSet.Service) foreach ($permission in $dataSet.Permissions) { $null = $graph.Add($permission) } foreach ($role in $dataSet.Roles) { $null = $roles.Add($role) } } } if ($Extra) { $null = $services.Add('Graph') } [pscustomobject]@{ PSTypeName = 'Argus.RequiredPermission' CheckId = $CheckId Title = $Title PermissionType = $permissionType Services = [string[]]@($services) GraphPermissions = [string[]]@($graph) DirectoryRoles = if ($AsAppPermission) { [string[]]@() } else { [string[]]@($roles) } ExchangePermission = if ($services.Contains('Exchange')) { $exchangePermission } else { $null } Licenses = [string[]]@($licenses) } } if ($Aggregate) { $result = & $describe $checks '(all selected checks)' 'Permissions requested by Connect-Argus' $script:ArgusCorePermissions if (-not $AsAppPermission) { $result | Add-Member -NotePropertyName RecommendedRoles -NotePropertyValue ([string[]]$script:ArgusRecommendedRoles) } return $result } foreach ($check in $checks) { & $describe @($check) $check.Id $check.Title @() } } |