Operators:
Recently, Entra ID team pulled off -contains
operator from dynamic group creation UI but it still can be used in rule builder. While we wait for an official communication/documentation update by Entra ID team, I did some analysis with Graph queries on Entra ID device and user objects to find the supported operators and parameters. From the testing, it is evident that the –contains
function is not supported, while -startsWith
function is supported through Graph.
As per above analysis, using the
-contains
function could prove costly as the data processing needs to be done outside of Graph.
Properties:
Also from the documentation on Advanced query parameters, there are non-indexed properties that are not available through Graph filters.
While, I couldn’t find a list of indexed vs non-indexed properties available publicly, I did more research and found that user resource type and device resource type documentation lists properties along with information whether $filter
parameter is supported and if supported, also provides list of allowed
operators
.
Let’s experiment with 3 properties as below.
Property Name | Supportability |
---|---|
| Documented and tested that it does not support $filter |
| No documentation on $filter support. But when tested with Graph queries, it supports $filter with advanced query parameters: -Countvariable and -ConsistencyLevel |
| Documented and tested that it supports |
As per above analysis, If we use a
property
that is supported through$filter
parameter along with asupported operator
as per the documentation, the dynamic device evaluation is expected to be done within the Graph. Else like
where
-object clause in PS, the entire set of users/devices needs to be processed which will increase the membership evaluation time.
What next?
Here is a PS snippet to get a html report of all dynamic groups along with membership rules. You can review the rules for any such properties (like deviceCategory
) or operators (especially –contains, -match
etc.,), test it through Graph API and modify accordingly to match your oraganizational requirements.
<#
DISCLAIMER STARTS
THIS SAMPLE CODE IS PROVIDED FOR THE PURPOSE OF ILLUSTRATION ONLY AND IS NOT INTENDED TO BE USED IN A PRODUCTION ENVIRONMENT. THIS SAMPLE CODE AND ANY RELATED INFORMATION ARE PROVIDED IS "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE."
DISCLAIMER ENDS
#>
#Set Report Location Variables
$ReportLocation = "C:\Windows\Temp"
$ReportName = "Entra-DynamicGroups-Report-$(get-date -format "yyyy-M-dd").html"
$ReportPath = "$ReportLocation\$ReportName"
#Connect with MS Graph
Connect-MgGraph -Scopes GroupMember.Read.All
#Get list of all Dynamic Groups
$DynamicGroups = Get-MgGroup -Filter "groupTypes/any(s:s eq 'DynamicMembership')" -All | Select Id,DisplayName,Description,CreatedDateTime,MembershipRule
$userDynamicGroups = $DynamicGroups | where {$_.MembershipRule -match "user\."}
$deviceDynamicGroups = $DynamicGroups | where {$_.MembershipRule -match "device\."}
#Create header for HTML Report
$Head = "<style>"
$Head +="BODY{background-color:#CCCCCC;font-family:Calibri,sans-serif; font-size: small;}"
$Head +="TABLE{border-width: 1px;border-style: solid;border-color: black;border-collapse: collapse; width: 98%;}"
$Head +="TH{border-width: 1px;padding: 0px;border-style: solid;border-color: black;background-color:#293956;color:white;padding: 5px; font-weight: bold;text-align:left;}"
$Head +="TD{border-width: 1px;padding: 0px;border-style: solid;border-color: black;background-color:#F0F0F0; padding: 2px;}"
$Head +="</style>"
#Create Report contents
$ReportOutput = "<h1>Dynamic Groups</h1>"
$ReportOutput += "<p>Total Dynamic Groups : $($DynamicGroups.Count)</p>"
$ReportOutput += "<h2>Dynamic User Groups</h2>"
$ReportOutput += "<p>Total Dynamic User Groups : $($userDynamicGroups.Count)</p>"
$ReportOutput += $userDynamicGroups | ConvertTo-Html -Fragment
$ReportOutput += "<h2>Dynamic Device Groups</h2>"
$ReportOutput += "<p>Total Dynamic Device Groups : $($deviceDynamicGroups.Count)</p>"
$ReportOutput += $deviceDynamicGroups | ConvertTo-Html -Fragment
#Generate Report
ConvertTo-HTML -head $Head -body "$ReportOutput" | Out-File $ReportPath
#Open Report
Invoke-Item $ReportPath