Skip to content

Testing Scenarios — Audit Logging Compliance Automation (ALCA)

15 test scenarios for validating the ALCA solution, plus a troubleshooting guide for 10 common issues.


Detection Scenarios

Scenario 1: All Environments Compliant

Setup: All Power Platform environments have Purview unified audit enabled. All Dataverse environments have org-level audit enabled.

Expected results: - All environments show Compliant status - Summary: N/N compliant, 0 non-compliant, 0 errors - Dataverse records all have fsi_compliancestatus = 100000000 (Compliant)

Verification: 1. Run Test-AuditLoggingCompliance.ps1 with required parameters 2. Verify console output shows all environments as Compliant 3. Check Dataverse table for matching records

Scenario 2: Mixed Compliance (Compliant + Non-Compliant)

Setup: At least one environment has Purview audit enabled and one does not. At least one Dataverse environment has org-level audit disabled.

Expected results: - Mix of Compliant and Non-Compliant statuses - Summary reflects accurate counts - Non-compliant records have fsi_compliancestatus = 100000001

Verification: 1. Run detection runbook 2. Verify per-environment status matches actual configuration 3. Confirm Dataverse records have correct status values

Scenario 3: Purview Unified Audit Disabled

Setup: Disable Purview unified audit log ingestion for a test environment via Set-AdminAuditLogConfig.

Expected results: - Affected environment shows Non-Compliant - fsi_auditenabled = false in Dataverse record - Other environments unaffected

Verification: 1. Disable audit: Set-AdminAuditLogConfig -UnifiedAuditLogIngestionEnabled $false 2. Run detection runbook 3. Verify environment shows Non-Compliant with PurviewAuditEnabled = False

Scenario 4: Audit Event Validation

Setup: Environment with audit enabled but no recent audit events in last 7 days.

Expected results: - Environment still shows Compliant if audit configuration is correct (event presence is informational, not a compliance gate) - LastAuditEvent field shows "None in last 7 days"

Verification: 1. Run detection on an environment with audit enabled 2. Verify LastAuditEvent column in CSV output 3. Confirm compliance status based on configuration, not event presence


Remediation Scenarios

Scenario 5: WhatIf Mode

Setup: Non-compliant environments exist. Run with -WhatIf switch.

Expected results: - Console shows [WHATIF] Would enable... for each action - No actual changes made to any environment - No Dataverse compliance records updated - Summary shows all actions as simulated

Verification: 1. Run Enable-AuditLogging.ps1 -WhatIf 2. Verify [WHATIF] prefix on all action lines 3. Confirm environment audit settings unchanged after run 4. Verify Dataverse records unchanged

Scenario 6: Dataverse Org-Level Audit Enablement

Setup: A Dataverse environment with isauditenabled = false.

Expected results: - Runbook enables org-level audit via PATCH to /api/data/v9.2/organizations - Entity-level audit enabled on 6 entities - Validation confirms changes after 5-second wait - Dataverse record updated to Compliant

Verification: 1. Confirm isauditenabled = false before remediation 2. Run remediation runbook (without WhatIf) 3. Verify isauditenabled = true via Dataverse Web API 4. Check entity audit settings for bot, botcomponent, connectionreference, environmentvariablevalue, workflow, systemuser

Scenario 7: Tenant-Wide Purview Unified Audit Enablement

Setup: Purview unified audit disabled at tenant level. Run with -EnableTenantUnifiedAudit.

Expected results: - Console shows tenant-wide change warning - Set-AdminAuditLogConfig -UnifiedAuditLogIngestionEnabled $true is called - All environments benefit from tenant-level change

Verification: 1. Verify current state: (Get-AdminAuditLogConfig).UnifiedAuditLogIngestionEnabled 2. Run remediation with -EnableTenantUnifiedAudit 3. Verify post-state: (Get-AdminAuditLogConfig).UnifiedAuditLogIngestionEnabled -eq $true

Scenario 8: Validation Failure After Remediation

Setup: Environment where audit enablement is applied but validation re-read still shows disabled (e.g., propagation delay exceeds 5 seconds).

Expected results: - Remediation actions are attempted - Validation re-read fails - Status set to Remediation Pending (not Compliant) - Environment flagged for follow-up in summary

Verification: 1. This scenario is typically transient — run detection again after 60 seconds 2. If persistent, check Dataverse for fsi_compliancestatus = 100000002


Infrastructure Scenarios

Scenario 9: Retry and Throttling (429)

Setup: High-volume tenant with many environments that may trigger API throttling.

Expected results: - Invoke-WithRetry handles 429 responses with exponential backoff - Verbose output shows retry attempts and delays - Scanning completes successfully (may take longer)

Verification: 1. Run detection with -Verbose to see retry logs 2. Verify all environments are processed despite throttling 3. Check that no environments are skipped

Scenario 10: Multi-Recipient Email Notification

Setup: Configure -NotificationToAddresses with multiple comma-separated recipients.

Expected results: - HTML email sent to all recipients - CSV attachment included - Email subject includes compliance counts - saveToSentItems = false (shared mailbox)

Verification: 1. Run detection with -SendEmail -NotificationToAddresses "user1@example.com,user2@example.com" 2. Verify all recipients received the email 3. Verify CSV attachment is present and contains all environment data

Scenario 11: Dataverse Upsert — Create New Record

Setup: First-time scan of an environment not yet in the compliance table.

Expected results: - Write-DataverseComplianceRecord queries for existing record (GET returns empty) - Creates new record via POST - Record has correct environment ID, name, audit status, and compliance status

Verification: 1. Verify environment has no existing record in fsi_auditenvironmentcompliances 2. Run detection 3. Verify new record created with correct field values

Scenario 12: Dataverse Upsert — Update Existing Record

Setup: Re-scan an environment that already has a compliance record.

Expected results: - Write-DataverseComplianceRecord finds existing record (GET returns match) - Updates record via PATCH (not POST) - fsi_lastchecked timestamp updated - Status reflects current compliance state

Verification: 1. Note the existing record's fsi_lastchecked value 2. Run detection 3. Verify fsi_lastchecked updated, record ID unchanged


Error Handling Scenarios

Scenario 13: Per-Environment Error (Continue Scanning)

Setup: An environment that causes an error (e.g., Dataverse API returns 403 for one environment).

Expected results: - Error caught per-environment, does not stop scanning - Error environment gets ComplianceStatus = Error with error message - Remaining environments processed normally - Summary includes error count

Verification: 1. Verify environment with restricted access exists 2. Run detection 3. Confirm error environment shows Error status with descriptive message 4. Confirm all other environments still processed

Scenario 14: Fatal Authentication Failure

Setup: Revoke Managed Identity permissions (e.g., remove Power Platform Administrator role).

Expected results: - Authentication fails immediately at Step 1 - Runbook exits with error (does not proceed to scanning) - Error message indicates authentication failure - No Dataverse records written

Verification: 1. Temporarily remove MI role assignment 2. Run detection 3. Verify [FATAL] message in output 4. Restore MI role assignment after test

Scenario 15: Scheduled Execution

Setup: Link the detection runbook to a schedule (see Scheduling Guide).

Expected results: - Runbook executes automatically at scheduled time - Job status shows Completed - Dataverse records updated - Email sent (if configured)

Verification: 1. Configure schedule per scheduling guide 2. Wait for scheduled execution 3. Check Automation AccountJobs for completed job 4. Verify Dataverse compliance records updated 5. Verify email received (if SendEmail configured)


Troubleshooting Guide

Issue 1: Power Platform Authentication Failure

Symptoms: - [FATAL] Power Platform authentication failed - Error: Add-PowerAppsAccount : The token could not be acquired

Possible causes: - Managed Identity not assigned Power Platform Administrator role - MI not enabled on the Automation Account - Incorrect tenant domain

Resolution: 1. Verify MI is enabled: Automation AccountIdentity → Status = On 2. Verify role: Entra IDRoles and administratorsPower Platform Administrator → Check MI is listed 3. Test token acquisition in Test Pane: Get-ManagedIdentityToken -Resource "https://api.bap.microsoft.com/"

Issue 2: Exchange Online Authentication Failure

Symptoms: - [FATAL] Exchange Online authentication failed - Error: Connect-ExchangeOnline : Failed to acquire token

Possible causes: - Managed Identity not assigned Exchange Online Admin role - ExchangeOnlineManagement module not imported or wrong version - Incorrect -Organization parameter

Resolution: 1. Verify role: Entra IDRoles and administratorsExchange Online Admin → Check MI is listed 2. Verify module: Automation AccountModulesExchangeOnlineManagement Status = Available on Runtime 7.2 3. Verify TenantDomain parameter matches yourdomain.onmicrosoft.com format

Issue 3: Dataverse 401 Access Denied

Symptoms: - Dataverse API calls fail with 401 Unauthorized - Error in Invoke-DataverseRequest: The user is not a member of the organization

Possible causes: - MI not added as Application User in the target Dataverse environment - Application User does not have System Administrator role - Token scoped to wrong Dataverse URL

Resolution: 1. Navigate to Power Platform Admin Center → target environment → SettingsApplication users 2. Verify MI is listed as an Application User 3. Verify the assigned security role is System Administrator 4. Ensure DataverseEnvironmentUrl parameter matches the governance environment URL

Issue 4: Email Not Sent

Symptoms: - [ERROR] Failed to send email - Error: MailboxNotEnabledForRESTAPI or AccessDenied

Possible causes: - MI does not have Mail.Send Graph application permission - Admin consent not granted for Mail.Send - Shared mailbox does not have SendAs permission for MI - Incorrect NotificationFromAddress

Resolution: 1. Verify Graph permission: Use Get-MgServicePrincipalAppRoleAssignment to check Mail.Send 2. Grant admin consent: Enterprise Applications → MI → PermissionsGrant admin consent 3. Verify SendAs: Get-RecipientPermission -Identity "shared-mailbox@domain.com" | Where Trustee -match "MI-name" 4. Ensure NotificationFromAddress matches the shared mailbox address exactly

Issue 5: Dataverse Table Not Updated

Symptoms: - Detection runs without errors but no records appear in fsi_auditenvironmentcompliances - Or records appear but fields are not updated

Possible causes: - Table does not exist (schema not deployed) - Alternate key not configured on fsi_environmentid - Dataverse token scoped to wrong environment

Resolution: 1. Verify table exists: Navigate to DataverseTables → Search for Audit Environment Compliance 2. Run the schema creation script: python create_audit_compliance_schema.py 3. Verify DataverseEnvironmentUrl points to the governance environment (not a target environment)

Issue 6: 429 Throttling (Too Many Requests)

Symptoms: - Verbose logs show multiple retry attempts - Runbook takes significantly longer than expected - Error: 429 Too Many Requests in verbose output

Possible causes: - Large number of environments (50+) causing API rate limits - Concurrent automation scripts hitting same APIs - Power Platform API throttling limits reached

Resolution: 1. This is handled automatically by Invoke-WithRetry with exponential backoff 2. If persistent, increase MaxRetries parameter in function calls 3. Consider staggering scheduled runs to avoid peak API usage times 4. For 100+ environments, consider batching (future enhancement)

Issue 7: Validation Failure After Remediation

Symptoms: - Remediation runs but validation step shows audit still disabled - Status set to Remediation Pending instead of Compliant

Possible causes: - Propagation delay exceeds the 5-second wait - Cached API response returning stale data - Insufficient permissions to modify entity definitions

Resolution: 1. Wait 60 seconds and re-run detection to check actual state 2. If still failing, increase the propagation wait (modify Start-Sleep in runbook) 3. Verify MI has System Administrator role in the target environment 4. Check entity-level audit settings manually via Dataverse Web API

Issue 8: Search-UnifiedAuditLog Cmdlet Not Found

Symptoms: - Error: The term 'Search-UnifiedAuditLog' is not recognized - Or: Search-UnifiedAuditLog requires Exchange Online connection

Possible causes: - ExchangeOnlineManagement module not imported - Exchange Online not connected before searching - Module version incompatible with PowerShell 7.2

Resolution: 1. Verify module: Automation AccountModulesExchangeOnlineManagement Runtime 7.2 → Status: Available 2. Ensure Connect-ExchangeOnline succeeds before Search-UnifiedAuditLog 3. Update module to latest version if Status shows issues

Issue 9: CSV Export Path Failure

Symptoms: - Error writing CSV to $env:TEMP - Export-Csv : Access to the path is denied

Possible causes: - $env:TEMP not defined in Azure Automation context - Disk space issue in sandbox

Resolution: 1. Azure Automation runbooks have access to $env:TEMP by default 2. If failing, use a hardcoded fallback: $csvPath = "C:\Temp\AuditCompliance.csv" 3. Verify the CSV is generated correctly in the Test Pane before scheduling

Issue 10: WhatIf Not Working (Changes Still Applied)

Symptoms: - Running with -WhatIf still makes actual changes - Environments are modified despite WhatIf flag

Possible causes: - Incorrect WhatIf parameter binding - SupportsShouldProcess not properly configured in CmdletBinding

Resolution: 1. Verify the script is using $PSCmdlet.ShouldProcess() gates around all modification calls 2. Ensure -WhatIf is passed at the command line (not just referenced as a variable) 3. Test with: .\Enable-AuditLogging.ps1 -DataverseEnvironmentUrl $url -TenantDomain $domain -WhatIf 4. Verify [WHATIF] prefix appears in output for each would-be action


Updated: February 2026 | Version: v1.0.3