Private/Write-NSPConditionalAccessProgress.ps1

function Write-NSPConditionalAccessProgress {
    <#
    .SYNOPSIS
        Shows what the tool is doing behind the scenes as a PowerShell progress bar, one bar per kind of work.
    .DESCRIPTION
        Each -Activity has a fixed bar ID and title, so nested work (an inventory taken during a
        dashboard task) shows as separate bars and -Completed removes the right one. The title says
        whether the work reads or writes. -Step and -Of give the percentage. Respects
        $ProgressPreference, so scripts and the scheduled job can silence it.
    #>

    [CmdletBinding()]
    param(
        [Parameter(Mandatory)][ValidateSet('Dashboard', 'Inventory', 'Run', 'Impact', 'Coverage', 'Overlap', 'SignIn', 'PublicAddress')][string]$Activity,
        [string]$Status = 'Working',
        [int]$Step,
        [int]$Of,
        [switch]$Completed
    )

    $bars = @{
        Dashboard = @(1, 'Working out each policy''s status (offline)')
        Inventory = @(2, 'Updating the inventory (reading the tenant through Graph)')
        Run = @(3, 'Running the approved items (writing to the tenant through Graph)')
        Impact = @(4, 'Reading report-only sign-in results (Graph)')
        Coverage = @(5, 'Checking MFA coverage (reading users and groups)')
        Overlap = @(6, 'Checking travel group members (Graph)')
        SignIn = @(7, 'Signing in')
        PublicAddress = @(8, 'Looking up this computer''s public IP address (internet)')
    }
    $id, $title = $bars[$Activity]
    # A call without -Of (a retry wait inside a stage) keeps the bar's last position.
    if ($null -eq $script:ProgressPosition) { $script:ProgressPosition = @{} }
    if ($Completed) {
        $script:ProgressPosition.Remove($Activity)
        Write-Progress -Id $id -Activity $title -Completed
        return
    }
    if ($Of -gt 0) { $script:ProgressPosition[$Activity] = @($Step, $Of) }
    elseif ($script:ProgressPosition.ContainsKey($Activity)) { $Step, $Of = $script:ProgressPosition[$Activity] }
    $arguments = @{ Id = $id; Activity = $title; Status = $(if ($Status) { $Status } else { 'Working' }) }
    if ($Of -gt 0) {
        $arguments.PercentComplete = [int][Math]::Min(100, [Math]::Max(0, 100 * $Step / $Of))
        $arguments.Status = "$($arguments.Status) ($Step of $Of)"
    }
    Write-Progress @arguments
}