Public/Test-EGIDynamicGroupRule.ps1
|
function Test-EGIDynamicGroupRule { <# .SYNOPSIS Simulates a dynamic group membership rule against many users at once. .DESCRIPTION Microsoft Entra's own "Validate rules" tab only checks up to 20 users/devices per run. This function evaluates a rule against an arbitrary number of user objects (e.g. your whole tenant) locally, so you can answer "who would join or leave this group if I change the rule this way" before saving anything. Supports the common comparison operators and a best-effort '-any(...)' handling. Does NOT support: direct-reports rules, the memberOf (preview) operator, or employeeHireDate date-math against system.now - such leaves raise a clear error instead of a silently wrong result. .PARAMETER Rule The raw dynamic membership rule string to test. .PARAMETER Users An array of user objects. Property names must match the Graph attribute names used in the rule (department, jobTitle, otherMails, employeeId, ...), case-insensitive. Typically produced with: Get-MgUser -All -Property Id,DisplayName,Department,JobTitle,UserType,Country .PARAMETER PassThru Return only the users that match the rule, instead of a full pass/fail table. .EXAMPLE $users = Get-MgUser -All -Property Id,DisplayName,Department,Country Test-EGIDynamicGroupRule -Rule '(user.department -eq "Sales") -and (user.country -eq "DE")' -Users $users #> [CmdletBinding()] param( [Parameter(Mandatory)] [string] $Rule, [Parameter(Mandatory)] [object[]] $Users, [switch] $PassThru ) $tree = ConvertFrom-EGIRuleString -Rule $Rule $results = [System.Collections.Generic.List[pscustomobject]]::new() $errorCount = 0 foreach ($user in $Users) { $displayName = $null foreach ($p in $user.PSObject.Properties) { if ($p.Name -ieq 'DisplayName') { $displayName = $p.Value } } try { $match = Test-EGIRuleTreeNode -Node $tree -User $user $results.Add([pscustomobject]@{ DisplayName = $displayName Matches = $match Error = $null }) } catch { $errorCount++ $results.Add([pscustomobject]@{ DisplayName = $displayName Matches = $null Error = $_.Exception.Message }) } } if ($errorCount -gt 0) { Write-Warning "$errorCount of $($Users.Count) user(s) could not be evaluated - see the Error column (unsupported rule constructs)." } if ($PassThru) { return $results | Where-Object { $_.Matches -eq $true } } return $results } |