Public/Start-IntuneAccess.ps1
|
function Start-IntuneAccess { <# .SYNOPSIS Signs in, collects tenant Intune RBAC data, creates a local HTML explorer and opens it. .DESCRIPTION Provides the guided IntuneAccess workflow for an interactive end user. It collects administrators and objects connected to Intune RBAC role assignments, plus supported Intune policy, application, script and update assignments. The optional user principal name selects the initial administrator in the explorer. .PARAMETER UserPrincipalName The administrator to select initially in the explorer. Tenant-wide RBAC data is still collected. .PARAMETER Feature Selects the read-only feature scopes used for the connection. Core, AssignmentExplorer, OperationalEvidence, PolicyAnalysis and AuditEvidence are the defaults. .PARAMETER Path Destination HTML file. A timestamped file in Documents is used by default. .PARAMETER SnapshotPath Optional destination for the current local JSON snapshot. .PARAMETER BaselineSnapshotPath Optional earlier snapshot to compare with the current collection. When supplied, a current snapshot is saved even when SnapshotPath is omitted. .PARAMETER RedactSnapshotIdentity Pseudonymises tenant and identity values in the saved snapshot. .PARAMETER NoOpen Creates the report without opening it in the default browser. .PARAMETER Force Replaces an existing report when an explicit Path is used. .EXAMPLE Start-IntuneAccess .EXAMPLE Start-IntuneAccess -UserPrincipalName 'helpdesk.user@contoso.com' #> [CmdletBinding()] param( [ValidateNotNullOrEmpty()] [string] $UserPrincipalName, [ValidateSet('Core', 'AssignmentExplorer', 'OperationalEvidence', 'PolicyAnalysis', 'AuditEvidence', 'ScopeTagAudit', 'ExtendedScopeTagAudit', 'ManagedDeviceAccess')] [string[]] $Feature = @('Core', 'AssignmentExplorer', 'OperationalEvidence', 'PolicyAnalysis', 'AuditEvidence'), [ValidateNotNullOrEmpty()] [string] $Path, [ValidateNotNullOrEmpty()] [string] $SnapshotPath, [ValidateNotNullOrEmpty()] [string] $BaselineSnapshotPath, [switch] $NoOpen, [switch] $RedactSnapshotIdentity, [switch] $Force ) $activity = 'IntuneAccess tenant RBAC explorer' try { Write-Progress -Activity $activity -Status 'Opening delegated Microsoft Graph sign-in' -PercentComplete 5 $connection = Connect-IntuneAccess -Feature $Feature $initialUser = if ([string]::IsNullOrWhiteSpace($UserPrincipalName)) { [string] $connection.Account } else { $UserPrincipalName.Trim() } Write-Progress -Activity $activity -Status 'Collecting Intune role assignments and connected objects' -PercentComplete 30 $tenantRbac = Get-IntuneAccessTenantRbac ` -InitialUserPrincipalName $initialUser ` -IncludeWorkloadAssignments:('AssignmentExplorer' -in $Feature) ` -IncludeOperationalEvidence:('OperationalEvidence' -in $Feature) ` -IncludePolicyAnalysis:('PolicyAnalysis' -in $Feature) ` -IncludeAuditEvidence:('AuditEvidence' -in $Feature) if ([string]::IsNullOrWhiteSpace($Path)) { $documentsPath = [Environment]::GetFolderPath([Environment+SpecialFolder]::MyDocuments) if ([string]::IsNullOrWhiteSpace($documentsPath)) { $documentsPath = (Get-Location).ProviderPath } $tenantName = [string] (Get-IntuneAccessProperty $tenantRbac.Tenant 'DisplayName' 'tenant') $safeTenantName = ($tenantName -replace '[^A-Za-z0-9._-]', '-').Trim('-') $timestamp = Get-Date -Format 'yyyyMMdd-HHmmss' $Path = Join-Path $documentsPath "IntuneAccess-$safeTenantName-$timestamp.html" } $snapshot = $null $snapshotComparison = $null if (-not [string]::IsNullOrWhiteSpace($SnapshotPath) -or -not [string]::IsNullOrWhiteSpace($BaselineSnapshotPath)) { if ([string]::IsNullOrWhiteSpace($SnapshotPath)) { $SnapshotPath = [IO.Path]::ChangeExtension($Path, '.snapshot.json') } Write-Progress -Activity $activity -Status 'Saving the local evidence snapshot' -PercentComplete 70 $snapshot = $tenantRbac | Export-IntuneAccessSnapshot -Path $SnapshotPath -RedactIdentity:$RedactSnapshotIdentity -Force:$Force if (-not [string]::IsNullOrWhiteSpace($BaselineSnapshotPath)) { $snapshotComparison = Compare-IntuneAccessSnapshot -ReferencePath $BaselineSnapshotPath -DifferencePath $snapshot.FullName -AuditEvent @(Get-IntuneAccessProperty $tenantRbac 'AuditEvents' @()) $tenantRbac | Add-Member -NotePropertyName SnapshotComparison -NotePropertyValue $snapshotComparison -Force } } Write-Progress -Activity $activity -Status 'Generating the self-contained Signal Atlas explorer' -PercentComplete 80 $report = $tenantRbac | Export-IntuneAccessReport -Path $Path -Force:$Force if (-not $NoOpen) { Write-Progress -Activity $activity -Status 'Opening the explorer in the default browser' -PercentComplete 95 Invoke-Item -LiteralPath $report.FullName } [PSCustomObject] @{ PSTypeName = 'IntuneAccess.RunResult' ConnectedAccount = [string] $connection.Account Tenant = [string] $tenantRbac.Tenant.DisplayName Administrators = @($tenantRbac.Administrators).Count RoleAssignments = @($tenantRbac.RoleAssignments).Count WorkloadObjects = @(Get-IntuneAccessProperty $tenantRbac 'WorkloadObjects' @()).Count WorkloadAssignments = @(Get-IntuneAccessProperty $tenantRbac 'WorkloadAssignments' @()).Count ManagedDevices = @(Get-IntuneAccessProperty $tenantRbac 'ManagedDevices' @()).Count DeploymentOutcomes = @(Get-IntuneAccessProperty $tenantRbac 'DeploymentOutcomes' @()).Count SnapshotPath = if ($null -eq $snapshot) { '' } else { [string] $snapshot.FullName } SnapshotChanges = if ($null -eq $snapshotComparison) { 0 } else { @($snapshotComparison.Changes).Count } PolicySettings = @(Get-IntuneAccessProperty $tenantRbac 'PolicySettings' @()).Count PotentialPolicyConflicts = @(Get-IntuneAccessProperty $tenantRbac 'PolicyConflictFindings' @() | Where-Object FindingState -EQ 'PotentialConflict').Count AuditEvents = @(Get-IntuneAccessProperty $tenantRbac 'AuditEvents' @()).Count ReportPath = [string] $report.FullName Opened = -not $NoOpen.IsPresent ReadOnly = $true ToolVersion = $script:IntuneAccessVersion } } finally { Write-Progress -Activity $activity -Completed } } |