AAD dynamic group syntax

Arif Usman 426 Reputation points

Trying to create User Dynamic security group with all users. here is my syntax, it works except for my exception (-not (user.userPrincipalName -startswith "Z-") OR (user.userPrincipalName -notstartswith "Z-") OR (user.userPrincipalName -notcontains "Z-")

I tried with this:
(user.objectId -ne null) -and (user.userType -eq "Member") -and -not (user.userPrincipalName -startswith "Z-")

(user.objectId -ne null) -and (user.userType -eq "Member") -and (user.userPrincipalName -notstartswith "Z-")


(user.objectId -ne null) -and (user.userType -eq "Member") -and (user.userPrincipalName -notcontains "Z-")

Any help?

Microsoft Entra ID
Microsoft Entra ID
A Microsoft Entra identity service that provides identity management and access control capabilities. Replaces Azure Active Directory.
20,468 questions
{count} votes

Accepted answer
  1. Shashi Shailaj 7,581 Reputation points Microsoft Employee

    Hello @usarif,

    The comment section is limited to 1000 chars hence I am posting the explanation in new post here. As explained by my colleague Saurabh above the given rule should work and it may need some more troubleshooting and we may need more details on the requirements. As of now I understand that we are trying to create a All Users group dynamically containing internal employees within your company. Let me list out the requirement below and then we will come to the dynamic query . I checked the article related to creating all Users rule.

    • The requirement is to create a All Users group dynamically containing all active user accounts which always contains the most updated list of active users within your company.
    • The first condition that we write for the same as per the article is user.objectId -ne null which only makes the dynamic query collect objects with a valid objectId . this rule will add any B2B guest Id as well as Member ID.
    • Now the UserType for a local user is always Member so we will add another mandatory condition to this user.userType -eq "Member" .
    • Also the Username must not start with Z- . I assume these are vendors , suppliers or some external entities that your company may work with but are not full time employees. Out of the three variations you have suggested , I will use this one user.userPrincipalName -notStartsWith "Z-"
    • So the final query comes to be (user.objectId -ne null) and (user.userType -eq "Member") and (user.userPrincipalName -notStartsWith "Z-")
    • The one which you have mentioned would also work with a slight modification by adding parenthesis in the last expression. (user.objectId -ne null) -and (user.userType -eq "Member") -and (-not (user.userPrincipalName -startswith "Z-"))

    I tested the same in my test environment and both the above work. But there are some caveats that I found in this approach. If the goal is to build the most updated dynamic group of active employees excluding guests then why not use something like EmployeeID . In case you allocate an employee ID to guest or temp workers as well then this may not work.

    Also this failed for some guest account which had been converted to members by using powershell in my testing . I had a outlook.com account which have been provided Global admin access and the userType was changed to member using the powershell Get-AzureADUser -SearchString john@outlook.com | Set-AzureADUser -UserType member . So this then prompted me to test another condition where we allow only users with valid company email address. For example you would always know what all custom domains you have which are used to provide email addresses to your users. So you can use the expression as per your custom domains used in email suffix. I have taken customdomain1.com and so on for example. So the query becomes as below. Please substitute the customdomain1.com and so on with valid email domains from your company directory.

    (user.objectId -ne null) and (user.userType -eq "Member") and (user.userPrincipalName -notStartsWith "Z-") and ((user.proxyAddresses -contains "customdomain1.com") OR (user.proxyAddresses -contains "customdomain2.com") OR (user.proxyAddresses -contains "customdomain3.com"))

    The only maintainability that this adds is that you have to make sure that whenever your company adds a new custom domain and uses that for any email address within the company, the above may fail to include those users as the dynamic query will need to be changed to include new custom email domains as well.

    I am not exactly aware of the scenario/use case you have in your company so I am just providing suggestions on the basis of my understanding . In case the explanation in any of the posts helps you , please do accept as answer . If you have any further query regarding this , do let us know and we will be happy to help you further.

    Thank you.

    2 people found this answer helpful.

1 additional answer

Sort by: Most helpful
  1. Saurabh Sharma 23,786 Reputation points Microsoft Employee

    @Arif Usman I am not seeing any error while using your dynamic query and able to get the results fine. Only thing I see you are missing is end parenthesis ")" in your dynamic rule provided in the question. I have added missing parenthesis and it works for me.
    (-not (user.userPrincipalName -startswith "Z-") OR (user.userPrincipalName -notstartswith "Z-") OR (user.userPrincipalName -notcontains "Z-"))

    I have check the Validation Rules (Preview) to check if the query works or not for any specific user.
    Can you please be more specific what exactly you are trying to achieve with this validation rule if your ask is something else.