These scripts collect evidence using an already-authenticated delegated Microsoft Graph context. They never sign in, request consent, or write cloud configuration. Authentication tokens stay in memory; outputs contain selected claims, IDs, scopes, and configuration data. Review outputs before publishing.
Download the complete tools and evidence package. Keep Roundup.GraphRead.ps1 in the same directory as the scripts that load it.
- Get-RoundupReadinessAudit.ps1 collects role, risk-policy, and memberOf candidate evidence. Supply
ExpectedTenantId,OutputPath, and optionally isolated labPrincipalIdvalues. Every collection is paginated. Failed or partial coverage produces null authoritative counts; an unscanned area never becomes βzero affected.β - Get-RoleBoundaryTokenEvidence.ps1 verifies the separately authenticated operator and a recent independent admin snapshot. It verifies preconditions; it performs no permission exercise.
- Roundup.GraphRead.ps1 contains shared functions. Its internal context holds an access token: never serialize the entire context. Serialize only
MetadataandMe. - Test-RoundupAuditOffline.ps1 runs fixture checks with no network fallback.
- Test-RoundupSnapshotExporters.ps1 checks that unrelated, partial, or missing inputs cannot overwrite historical reports. It uses synthetic files and needs no private lab records.
Supported auth sources are AzureCli, GraphPowerShell, and AccessToken. AccessToken requires a SecureString passed inside PowerShell, not a token interpolated into shell text. GraphPowerShell requires an existing delegated connection. AzureCli can use a dedicated AzureConfigDirectory without changing the normal profile.
The audit covers both v1.0 and beta Conditional Access inventories and explicitly marks the beta datasets. It does not establish the enabled state of old ID Protection risk policies; those remain ManualReviewRequired. It also does not prove license compliance, replacement-rule equivalence, or actual enforcement.
For role tests, use the independent administrative audit’s PrincipalId option for each disposable operator and target. Collect operator evidence using that operator’s token. Do not add broad audit permissions to the operator solely to collect its role assignments.
Verification: 14 offline checks passed on September 11, 2026 under PowerShell 7. Checks covered syntax, full pagination, mid-page permission failure, first-page denial, safe error output, cross-origin and cyclic next links, nested access-package membership rules, missing-rule coverage, and completed empty scans. No tenant behavior is inferred from these fixtures.
The public Get-RoundupReadinessAudit.ps1 was subsequently executed against the lab after additional delegated read scopes were granted only to the administrative reader. The run timestamp was September 12, 2026 at 00:07:46 UTC (September 11 in America/Chicago). It returned CompleteForListedGraphScopes: 8/8 collection scans and 5/5 principal checks completed. Directory-role eligibility coverage was resolved and returned zero instances. PIM eligibility for group membership or ownership remains outside coverage. The operator action-test scopes were unchanged.
The audit code issued only Graph GET requests. Its administrative token still included the TAP and authentication-method-policy write scopes used earlier for bootstrap; GET-only execution does not mean the token itself had only read permissions.
Sanitized results are available as readiness-summary.json and readiness-summary.md. Legacy user-risk and sign-in-risk enabled states were checked separately in the UI; both were disabled. This does not change the script’s intentional ManualReviewRequired output for legacy policies. role-results.json and role-results.md separately document the actual role action experiments and their limits.
Historical report builders
The two Export-Sanitized*.ps1 files reproduce the original experiment’s publication snapshots. They are not general formatters for a new audit: their original narrative includes fixed experimental circumstances. They now require the recorded source hashes (and the original manual-policy evidence for the readiness snapshot) and reject different input before writing output. Use the reusable audit collector’s JSON for a fresh inventory; do not apply a historical narrative to new or partial data. The private original source records are not distributed. Later follow-up notes are maintained separately from these snapshot builders.
