Removed extension attribute requirement for testing

This commit is contained in:
2026-08-21 00:31:47 -04:00
parent cdc6bb33d3
commit aeedb7170a
4 changed files with 125 additions and 4 deletions
@@ -149,6 +149,42 @@ function Get-PersonaGraphStatusCode {
return $null
}
function Test-PersonaTargetAttributeUnavailable {
<#
.SYNOPSIS
True when a Graph 400 means the target attribute does not exist in this
tenant, rather than some other client error.
.DESCRIPTION
A dev tenant with no app registration has no persona extension property.
Requesting it in $select then fails with 400 and a message naming the
property. This distinguishes that specific, recoverable case from every
other 400 (bad query syntax, an unrelated bad property, a permission denial
phrased as 400), which must still fail loudly rather than being swallowed.
.PARAMETER ErrorRecord
The error caught from Invoke-PersonaGraphRequest.
.PARAMETER TargetAttribute
The configured target attribute name.
#>
[CmdletBinding()]
[OutputType([bool])]
param(
[Parameter(Mandatory)] $ErrorRecord,
[Parameter(Mandatory)] [string] $TargetAttribute
)
if ((Get-PersonaGraphStatusCode -ErrorRecord $ErrorRecord) -ne 400) { return $false }
$text = @($ErrorRecord.Exception.Message, $ErrorRecord.ErrorDetails.Message) -join ' '
if ([string]::IsNullOrWhiteSpace($text)) { return $false }
if ($text -notmatch [regex]::Escape($TargetAttribute)) { return $false }
[bool]($text -match '(?i)could not find a property|invalid property|is not a valid property|does not exist on type')
}
function Get-PersonaRetryAfterMs {
<#
.SYNOPSIS
+26 -3
View File
@@ -98,9 +98,32 @@ function Invoke-PersonaEngineRun {
: @(Get-PersonaUsers -SelectProperties $selectProperties)
}
catch {
# A partial population is worse than none: half a tenant classified looks
# like a successful run to everything downstream.
return New-PersonaRunOutcome -Counters $counters -ExitCode $EXIT_ENUMERATION -FailureReason $_.Exception.Message
if ((-not $IsEnforcing) -and (Test-PersonaTargetAttributeUnavailable -ErrorRecord $_ -TargetAttribute $TargetAttribute)) {
# Dev/test tenants often have no app registration yet, so the persona
# extension property was never created. Preview mode never writes
# regardless of what StoredPersona holds, so treating the attribute as
# absent (null) here is safe and lets development proceed without one.
# Enforcement still fails loudly - IsEnforcing gates this precisely
# because writing to an attribute that does not exist must never be
# silently tolerated.
Write-Warning "Target attribute '$TargetAttribute' was not found in this tenant (no app registration / extension property?). Continuing in What-If mode with it treated as null for every account."
$fallbackProperties = @($selectProperties | Where-Object { $_ -cne $TargetAttribute })
try {
$users = $UserObjectId `
? @(Get-PersonaUsers -SelectProperties $fallbackProperties -UserObjectId $UserObjectId) `
: @(Get-PersonaUsers -SelectProperties $fallbackProperties)
}
catch {
return New-PersonaRunOutcome -Counters $counters -ExitCode $EXIT_ENUMERATION -FailureReason $_.Exception.Message
}
}
else {
# A partial population is worse than none: half a tenant classified looks
# like a successful run to everything downstream.
return New-PersonaRunOutcome -Counters $counters -ExitCode $EXIT_ENUMERATION -FailureReason $_.Exception.Message
}
}
foreach ($graphUser in $users) {