Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update Test-MtConditionalAccessWhatIf.ps1 #515

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
134 changes: 107 additions & 27 deletions powershell/public/Test-MtConditionalAccessWhatIf.ps1
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<#
<#
.SYNOPSIS
Tests Conditional Access evaluation with What If for a given scenario.

Expand All @@ -9,41 +9,50 @@

Learn more:
https://learn.microsoft.com/entra/identity/conditional-access/what-if-tool
https://learn.microsoft.com/en-us/powershell/module/microsoft.graph.beta.identity.signins/test-mgbetaidentityconditionalaccess?view=graph-powershell-beta

.EXAMPLE
Test-MtConditionalAccessWhatIf -UserId 7a6da1c3-616a-416b-a820-cbe4fa8e225e `
-IncludeApplications "00000002-0000-0ff1-ce00-000000000000" `
-ClientAppType exchangeActiveSync
Test-MtConditionalAccessWhatIf -UserId '7a6da1c3-616a-416b-a820-cbe4fa8e225e' `
-IncludeApplications '00000002-0000-0ff1-ce00-000000000000' `
-ClientAppType 'exchangeActiveSync'

This example tests the Conditional Access policies for a user signing into Exchange Online using a legacy Mail client that relies on basic authentication.

.EXAMPLE
Test-MtConditionalAccessWhatIf -UserId 7a6da1c3-616a-416b-a820-cbe4fa8e225e `
-UserAction registerOrJoinDevices
Test-MtConditionalAccessWhatIf -UserId '7a6da1c3-616a-416b-a820-cbe4fa8e225e' `
-UserAction 'registerOrJoinDevices'

This example tests the Conditional Access policies for a user registering or joining a device to Microsoft Entra.

.EXAMPLE
Test-MtConditionalAccessWhatIf -UserId 7a6da1c3-616a-416b-a820-cbe4fa8e225e `
Test-MtConditionalAccessWhatIf -UserId '7a6da1c3-616a-416b-a820-cbe4fa8e225e' `
-IncludeApplications '67ad5377-2d78-4ac2-a867-6300cda00e85' `
-Country FR -IpAddress '92.205.185.202'
-Country 'FR' -IpAddress '92.205.185.202'

This example tests the Conditional Access policies for a user signing into **Office 365** from **France** with a specific **IP address**.

.EXAMPLE
Test-MtConditionalAccessWhatIf -UserId 7a6da1c3-616a-416b-a820-cbe4fa8e225e `
Test-MtConditionalAccessWhatIf -UserId '7a6da1c3-616a-416b-a820-cbe4fa8e225e' `
-IncludeApplications '67ad5377-2d78-4ac2-a867-6300cda00e85' `
-SignInRiskLevel High -DevicePlatform iOS
-SignInRiskLevel 'High' -DevicePlatform 'iOS'

This example tests the Conditional Access policies for a user signing into **Office 365** from an **iOS** device with a **High** sign-in risk level.

.EXAMPLE
Test-MtConditionalAccessWhatIf -UserId 7a6da1c3-616a-416b-a820-cbe4fa8e225e `
-UserAction registerSecurityInformation `
-DevicePlatform Android `
-UserRiskLevel High
Test-MtConditionalAccessWhatIf -UserId '7a6da1c3-616a-416b-a820-cbe4fa8e225e' `
-IncludeApplications 'bbad9299-f060-4e15-9a9a-285980ae00fc' `
-DeviceInfo { 'isCompliant' = 'true'; 'Manufacturer' = 'Dell' } `
-InsiderRiskLevel 'Minor'

This example tests the Conditional Access policies for a user accessing the **My Security Info** page from an **Android** device with a **High** user risk level.
This example tests the Conditional Access policies for a user accessing an **application** from a **compliant**, **Dell** device with a **Minor** insider risk level.

.EXAMPLE
Test-MtConditionalAccessWhatIf -UserId '7a6da1c3-616a-416b-a820-cbe4fa8e225e' `
-IncludeApplications 'a7936c39-024c-4148-a9b3-f88f2e9406f6' `
-ServicePrincipalRiskLevel 'High' -Verbose -IncludeReportOnly -IncludeDisabled -PrettyJsonVerboseOutput

This example tests the Conditional Access policies for a service principal user accessing the **application** with a **High** service principal risk level.
It will return all applied results, including the report-only and disabled policies. It will print the Graph API input and output JSON objects in a pretty format.

.LINK
https://maester.dev/docs/commands/Test-MtConditionalAccessWhatIf
Expand Down Expand Up @@ -96,6 +105,55 @@ function Test-MtConditionalAccessWhatIf {
[ValidateSet("None", "Low", "Medium", "High")]
[string]$UserRiskLevel,

# Insider risk level for the test.
# Values can be Minor, Moderate, Elevated
[Parameter(ValueFromPipelineByPropertyName = $true)]
[ValidateSet("Minor", "Moderate", "Elevated")]
[string]$InsiderRiskLevel,

# Service Principal risk level for the test.
# Values can be None, Low, Medium, High
[Parameter(ValueFromPipelineByPropertyName = $true)]
[ValidateSet("None", "Low", "Medium", "High")]
[string]$ServicePrincipalRiskLevel,

# Device info to be used for the test.
# Values can be any key-value pair

#[DeviceInfo <IMicrosoftGraphDeviceInfo>]: deviceInfo
# [(Any) <Object>]: This indicates any property can be added to this object.
# [DeviceId <String>]:
# [DisplayName <String>]:
# [EnrollmentProfileName <String>]:
# [ExtensionAttribute1 <String>]:
# [ExtensionAttribute10 <String>]:
# [ExtensionAttribute11 <String>]:
# [ExtensionAttribute12 <String>]:
# [ExtensionAttribute13 <String>]:
# [ExtensionAttribute14 <String>]:
# [ExtensionAttribute15 <String>]:
# [ExtensionAttribute2 <String>]:
# [ExtensionAttribute3 <String>]:
# [ExtensionAttribute4 <String>]:
# [ExtensionAttribute5 <String>]:
# [ExtensionAttribute6 <String>]:
# [ExtensionAttribute7 <String>]:
# [ExtensionAttribute8 <String>]:
# [ExtensionAttribute9 <String>]:
# [IsCompliant <Boolean?>]:
# [Manufacturer <String>]:
# [MdmAppId <String>]:
# [Model <String>]:
# [OperatingSystem <String>]:
# [OperatingSystemVersion <String>]:
# [Ownership <String>]:
# [PhysicalIds <String- []>]:
# [ProfileType <String>]:
# [SystemLabels <String- []>]:
# [TrustType <String>]:
[Parameter(ValueFromPipelineByPropertyName = $true)]
[hashtable]$DeviceInfo,

# Country to be used for the test. The two-letter country code.
[Parameter(ValueFromPipelineByPropertyName = $true)]
[ValidateSet("AD", "AE", "AF", "AG", "AI", "AL", "AM", "AO", "AQ", "AR", "AS", "AT", "AU", "AW", "AX", "AZ", "BA", "BB", "BD", "BE", "BF", "BG", "BH", "BI", "BJ", "BL", "BM", "BN", "BO", "BQ", "BR", "BS", "BT", "BV", "BW", "BY", "BZ", "CA", "CC", "CD", "CF", "CG", "CH", "CI", "CK", "CL", "CM", "CN", "CO", "CR", "CU", "CV", "CW", "CX", "CY", "CZ", "DE", "DJ", "DK", "DM", "DO", "DZ", "EC", "EE", "EG", "EH", "ER", "ES", "ET", "FI", "FJ", "FK", "FM", "FO", "FR", "GA", "GB", "GD", "GE", "GF", "GG", "GH", "GI", "GL", "GM", "GN", "GP", "GQ", "GR", "GS", "GT", "GU", "GW", "GY", "HK", "HM", "HN", "HR", "HT", "HU", "ID", "IE", "IL", "IM", "IN", "IO", "IQ", "IR", "IS", "IT", "JE", "JM", "JO", "JP", "KE", "KG", "KH", "KI", "KM", "KN", "KP", "KR", "KW", "KY", "KZ", "LA", "LB", "LC", "LI", "LK", "LR", "LS", "LT", "LU", "LV", "LY", "MA", "MC", "MD", "ME", "MF", "MG", "MH", "MK", "ML", "MM", "MN", "MO", "MP", "MQ", "MR", "MS", "MT", "MU", "MV", "MW", "MX", "MY", "MZ", "NA", "NC", "NE", "NF", "NG", "NI", "NL", "NO", "NP", "NR", "NU", "NZ", "OM", "PA", "PE", "PF", "PG", "PH", "PK", "PL", "PM", "PN", "PR", "PS", "PT", "PW", "PY", "QA", "RE", "RO", "RS", "RU", "RW", "SA", "SB", "SC", "SD", "SE", "SG", "SH", "SI", "SJ", "SK", "SL", "SM", "SN", "SO", "SR", "SS", "ST", "SV", "SX", "SY", "SZ", "TC", "TD", "TF", "TG", "TH", "TJ", "TK", "TL", "TM", "TN", "TO", "TR", "TT", "TV", "TW", "TZ", "UA", "UG", "UM", "US", "UY", "UZ", "VA", "VC", "VE", "VG", "VI", "VN", "VU", "WF", "WS", "YE", "YT", "ZA", "ZM", "ZW")]
Expand All @@ -106,9 +164,24 @@ function Test-MtConditionalAccessWhatIf {
[Parameter(ValueFromPipelineByPropertyName = $true)]
[string]$IpAddress,

# Output all results
[Parameter()]
[switch]$AllResults
# Output all results, not only the applied policies.
[Parameter(ValueFromPipelineByPropertyName = $true)]
[switch]$AllResults,

# IncludeReportOnly
# Include report-only policies in the final resultset
[Parameter(ValueFromPipelineByPropertyName = $true)]
[switch]$IncludeReportOnly,

# IncludeDisabled
# Include disabled policies in the final resultset
[Parameter(ValueFromPipelineByPropertyName = $true)]
[switch]$IncludeDisabled,

# Pretty JSON verbose output
# Pretty print Whatif input and result JSON objects in verbose mode
[Parameter(ValueFromPipelineByPropertyName = $true)]
[switch]$PrettyJsonVerboseOutput
)

process {
Expand All @@ -132,7 +205,8 @@ function Test-MtConditionalAccessWhatIf {
}
}

$ConditionalAccessWhatIfDefinition = @{
$ConditionalAccessWhatIfBodyParameter = @{
"AppliedPoliciesOnly" = -not $AllResults
"conditionalAccessWhatIfSubject" = @{
"@odata.type" = "#microsoft.graph.userSubject"
"userId" = $UserId
Expand All @@ -141,27 +215,33 @@ function Test-MtConditionalAccessWhatIf {
"conditionalAccessWhatIfConditions" = @{}
}

$whatIfConditions = $ConditionalAccessWhatIfDefinition.conditionalAccessWhatIfConditions
$whatIfConditions = $ConditionalAccessWhatIfBodyParameter.conditionalAccessWhatIfConditions

if ($UserRiskLevel) { $whatIfConditions.userRiskLevel = $UserRiskLevel }
if ($InsiderRiskLevel) { $whatIfConditions.insiderRiskLevel = $InsiderRiskLevel }
if ($ServicePrincipalRiskLevel) { $whatIfConditions.servicePrincipalRiskLevel = $ServicePrincipalRiskLevel }
if ($SignInRiskLevel) { $whatIfConditions.signInRiskLevel = $SignInRiskLevel }
if ($ClientAppType) { $whatIfConditions.clientAppType = $ClientAppType }
if ($DevicePlatform) { $whatIfConditions.devicePlatform = $DevicePlatform }
if ($DeviceInfo) { $whatIfConditions.deviceInfo = $DeviceInfo }
if ($Country) { $whatIfConditions.country = $Country }
if ($IpAddress) { $whatIfConditions.ipAddress = $IpAddress }

Write-Verbose ( $ConditionalAccessWhatIfDefinition | ConvertTo-Json -Depth 99 -Compress )
Write-Verbose "ConditionalAccessWhatIfBodyParameter: $( $ConditionalAccessWhatIfBodyParameter | ConvertTo-Json -Depth 99 -Compress:($PrettyJsonVerboseOutput -eq $false) )"

try {
$ConditionalAccessWhatIfResult = Invoke-MgGraphRequest -Method POST -Uri "https://graph.microsoft.com/beta/identity/conditionalAccess/evaluate" -OutputType PSObject -Body ( $ConditionalAccessWhatIfDefinition | ConvertTo-Json -Depth 99 -Compress ) | Select-Object -ExpandProperty value
# Filter out policies that do not apply
if (!$AllResults) {
$ConditionalAccessWhatIfResult = $ConditionalAccessWhatIfResult | Where-Object { $_.policyApplies -eq $true }
}
$ConditionalAccessWhatIfResult = Test-MgBetaIdentityConditionalAccess -BodyParameter $ConditionalAccessWhatIfBodyParameter

$returnStates = @('enabled')
$returnStates += @('enabledForReportingButNotEnforced') * [bool]$IncludeReportOnly
$returnStates += @('disabled') * [bool]$IncludeDisabled
Write-Verbose "Including policies in result set with states: $returnStates"

$ConditionalAccessWhatIfResult = ($ConditionalAccessWhatIfResult | Where-Object { $_.state -in $returnStates })
Write-Verbose "ConditionalAccessWhatIfResult: $( $ConditionalAccessWhatIfResult | ConvertTo-Json -Depth 99 -Compress:($PrettyJsonVerboseOutput -eq $false) )"
return $ConditionalAccessWhatIfResult
} catch {
Write-Error $_.Exception.Message
}
}
}