Private/ConvertTo-CaEvaluateBody.ps1
|
function ConvertTo-CaEvaluateBody { <# .SYNOPSIS Builds the request body for one What If evaluation .DESCRIPTION Assembles the three required parts of the evaluate request - signInIdentity, signInContext and signInConditions - from a scenario. The verb is ConvertTo rather than New because nothing is created: a scenario goes in and the same information comes back out shaped for the API. New- belongs to functions that change something, and PSScriptAnalyzer is right to insist on the distinction. signInContext is an abstract type with three derived forms, and which one applies is decided by what the resource targets. An application sign-in is applicationContext with includeApplications, a user action is userActionContext with userAction, and an authentication context is authContext with authenticationContextValue. Getting the odata.type wrong is not a soft failure - Graph rejects the request - so the choice is made here from the scenario rather than left to the caller. appliedPoliciesOnly is pinned to false and is not a parameter. Every use this module has for a response needs the non-applying policies in it: without them a report-only policy that does not apply is indistinguishable from one that was never returned, and the projection quietly stops meaning anything. Making it configurable would only offer a way to break the module's own output. .PARAMETER Scenario A scenario from Expand-CaScenario. .OUTPUTS Hashtable ready to be serialised as the request body. .EXAMPLE $body = ConvertTo-CaEvaluateBody -Scenario $scenario $json = $body | ConvertTo-Json -Depth 10 .NOTES Author: Jeffrey Stuhr Version: 0.2.0 Last Updated: 2026-08-17 #> [CmdletBinding()] [OutputType([hashtable])] param( [Parameter(Mandatory)] [ValidateNotNull()] [object]$Scenario ) $userId = [string](Get-CaProperty -InputObject $Scenario -Name 'UserId') if ([string]::IsNullOrWhiteSpace($userId)) { throw "Scenario '$(Get-CaProperty -InputObject $Scenario -Name 'Name')' has no UserId." } $applicationId = [string](Get-CaProperty -InputObject $Scenario -Name 'ApplicationId') $userAction = [string](Get-CaProperty -InputObject $Scenario -Name 'UserAction') $authContext = [string](Get-CaProperty -InputObject $Scenario -Name 'AuthenticationContext') if (-not [string]::IsNullOrWhiteSpace($applicationId)) { $context = @{ '@odata.type' = '#microsoft.graph.applicationContext' includeApplications = @($applicationId) } } elseif (-not [string]::IsNullOrWhiteSpace($userAction)) { $context = @{ '@odata.type' = '#microsoft.graph.userActionContext' userAction = $userAction } } elseif (-not [string]::IsNullOrWhiteSpace($authContext)) { $context = @{ '@odata.type' = '#microsoft.graph.authContext' authenticationContextValue = $authContext } } else { throw ("Scenario '$(Get-CaProperty -InputObject $Scenario -Name 'Name')' targets " + 'no application, user action or authentication context.') } $conditions = Get-CaProperty -InputObject $Scenario -Name 'Conditions' if ($null -eq $conditions) { $conditions = @{} } return @{ signInIdentity = @{ '@odata.type' = '#microsoft.graph.userSignIn' userId = $userId } signInContext = $context signInConditions = $conditions # Pinned. See the description - the projection is meaningless without every policy. appliedPoliciesOnly = $false } } |