Private/Get-NSPConditionalAccessRunStage.ps1

function Get-NSPConditionalAccessRunStage {
    <#
    .SYNOPSIS
        The ordered stages an approved plan action runs through.
    .DESCRIPTION
        Every write is bracketed: VerifyTarget re-reads the tenant immediately before writing and
        refuses if it no longer matches the plan, and ConfirmApplied re-reads after writing so
        the ownership record holds what Graph actually stored.
    #>

    [CmdletBinding()]
    [OutputType([string[]])]
    param(
        [Parameter(Mandatory)][string]$Action
    )

    switch ($Action) {
        'Create' { @('VerifyTarget', 'CreatePolicy', 'ConfirmApplied', 'RecordOwnership') }
        { $_ -in 'AdoptOrReview', 'UpdateInPlace', 'Drifted' } { @('VerifyTarget', 'PatchPolicy', 'ConfirmApplied', 'RecordOwnership') }
        'CreateGroup' { @('VerifyTarget', 'CreateGroup', 'BindProfile') }
        'CreateNamedLocation' { @('VerifyTarget', 'CreateNamedLocation', 'BindProfile') }
        'CreateOnPremGroup' { @('WriteOnPremScript') }
        'PromoteState' { @('VerifyState', 'PatchState', 'ConfirmState') }
        'Retire' { @('VerifyRetire', 'DeletePolicy', 'ForgetTravel') }
        'BindSyncedGroup' { @('VerifySyncedGroup', 'BindProfile') }
        'DeleteNamedLocation' { @('VerifyUnreferenced', 'DeleteNamedLocation') }
        'CreateAuthenticationStrength' { @('VerifyTarget', 'CreateAuthenticationStrength', 'BindProfile') }
        'BindAuthenticationStrength' { @('VerifyStrength', 'BindProfile') }
        'AddCloudMember' { @('VerifyMember', 'AddMember') }
        'CreateTrustedLocation' { @('VerifyTrustedLocation', 'CreateNamedLocation') }
        { $_ -in 'UpdateTrustedLocation', 'UndoUpdateTrustedLocation' } { @('VerifyTrustedLocation', 'PatchNamedLocation', 'ConfirmTrustedLocation') }
        'UndoCreateTrustedLocation' { @('VerifyUnreferenced', 'DeleteNamedLocation') }
        { $_ -in 'DisableSecurityDefaults', 'EnableSecurityDefaults' } { @('VerifySecurityDefaults', 'PatchSecurityDefaults', 'ConfirmSecurityDefaults') }
        # Undo (New-NSPConditionalAccessUndoPlan). Each re-checks the tenant before writing.
        'UndoCreatePolicy' { @('VerifyTarget', 'DeletePolicy', 'ForgetOwnership') }
        'UndoAdopt' { @('VerifyTarget', 'PatchPolicy', 'ConfirmApplied', 'ForgetOwnership') }
        'UndoUpdate' { @('VerifyTarget', 'PatchPolicy', 'ConfirmApplied', 'RecordOwnership') }
        'UndoCreateGroup' { @('VerifyUnusedGroup', 'DeleteGroup', 'UnbindProfile') }
        'UndoCreateNamedLocation' { @('VerifyUnreferenced', 'DeleteNamedLocation', 'UnbindProfile') }
        'UndoCreateAuthenticationStrength' { @('VerifyUnusedStrength', 'DeleteAuthenticationStrength', 'UnbindProfile') }
        'UndoBind' { @('UnbindProfile') }
        'UndoDeleteNamedLocation' { @('VerifyTarget', 'CreateNamedLocation') }
        'UndoAddMember' { @('RemoveMember') }
        'UndoAddOnPremMember' { @('RemoveOnPremMember') }
        'AddOnPremMember' { @('AddOnPremMember') }
        default { throw "Action '$Action' cannot be executed." }
    }
}