Creating dynamic groups in Azure Active Directory using Graph API and C#

Dec 26, 2018 Dev
[Reading Time: 2 minutes]

In one of my projects I tried to create dynamic groups in AAD for organizing added users from a custom build sync tools I wrote. So, if you don’t know, what a dynamic group is, watch this video here. In short, it is a technique for a dynamic membership based on rules, that organize users by attributes values into groups – really great!

For my syncing tool I had the requirement, to create specific dyn. groups, if they aren’t existing based on a specific attributes value. So I had to do it by code (C# Graph API SDK). Unfortunately there is no good documentation on, how one can do this, os I like to share, what I found.

First note:

Use Graph API “beta” (not version 1.0). Writing in terms of Graph API Url:

https://graph.microsoft.com/beta/groups/ 

Second note:

use properties “membershipRule” (dynamic group rule) and “membershipRuleProcessingState” (for activating group as dynamic group).

If you are not sure, what properties you can use, try the following procedure:
– create a dynamic group by hand in AAD
– go to Graph explorer (Link here)
– use URL from above (https://graph.microsoft.com/beta/groups/)
– see response JSON
– (to get the differences between v1.0 and beta, you can switch version in dropdown and compare responses)

I used the Graph API SDK for C# to handle Graph API calls. So, I had to deal with the question “How can I add theses properties? They are not part of the model Group
But luckily I could use the property AdditionaData, that is a dictionary of string and object. There I added, my dynamic group properties and here we go – It worked like a charm.
See below code for clarification. This creates a dynamic group named Group_<Number>, adding user as members, that have a displayName containing “AA “. That’s all!

Hope this helps, cheers!

...
var group = new Microsoft.Graph.Group();
group.GroupTypes = new List<string> { "DynamicMembership" };
group.Description = $"Dynamic group called Group{div}";
group.DisplayName = $"Group_{div}";
group.MailEnabled = false;
group.MailNickname = $"Group{div}";
group.SecurityEnabled = true;
group.AdditionalData = new Dictionary<string, object>();
group.AdditionalData.Add("membershipRule", @"user.displayName -contains ""AA """);
group.AdditionalData.Add("membershipRuleProcessingState", "On");

try
{
  await client.Groups.Request().AddAsync(group);
  log.LogInformation($"Added group Group_{div}");
}
catch (ServiceException ex)
{
  log.LogError(ex, $"There was an exception on creating dynamic group {div}. This 
           is the inner error {JsonConvert.SerializeObject(ex.Error)}.");
  errors.Add(div.ToString());
}
...

By Thomas

As Chief Technology Officer at Xpirit Germany. I am responsible for driving productivity for our customers by a full stack of dev and technology in modern times. But I not only care for technologies from Microsofts stack like Azure, AI, and IoT, but also for delivering quality and expertise with DevOps

7 thoughts on “Creating dynamic groups in Azure Active Directory using Graph API and C#”
  1. Hi,
    Thanks for your example, i created a new dynamic group with your code but now i need to change the “membershipRule” and I’m getting a error.

    I already tried 2 ways and i get the same error:
    “Code: Authorization_RequestDenied
    Message: Insufficient privileges to complete the operation.”

    I don’t know if the problem it’s app permissions or something that i’m doing wrong.
    On azure I have this permissions on api permission
    Group.Read.All
    Group.ReadWrite.All

    Example1:
    var prop = new Dictionary();
    prop.Add(“membershipRule”, @”user.displayName -contains “”A “””);
    await graphClient.Groups[group1.Id].Request().UpdateAsync(new Group
    {
    AdditionalData = prop
    });

    Example2:
    group1.AdditionalData.Remove(“membershipRule”);
    group1.AdditionalData.Add(“membershipRule”, @”user.displayName -contains “”A “””);
    await graphClient.Groups[group1.Id].Request().UpdateAsync(group1);

    1. Hey Tiago,

      it seems to be a permission setting for registered application. I am not sure about your setup, but from documentation in Microsoft Doc, you need at least Group.ReadWrite.All & Directory.ReadWrite.All.

      If this does not the trick 🙂 How is updating the group in general? Can you update a removed rule?

  2. Thanks for your reply,
    I could for example change a description of the group that i created. But couldn’t change any key of AdditionalData.

    Now i had the Directory.ReadWrite.All permission and i still have the same error.

    Example to change the description:
    await graphClient.Groups[group1.Id].Request().UpdateAsync(new Group
    {
    Description = “Test Update Desc”,
    });

    1. Are you able, to set full permission set to your App for “application” and/or “delegate”? With that you can exclude permissions problems. It could be of following issue: https://github.com/microsoftgraph/msgraph-sdk-dotnet-auth/issues/47

      In parallel, I would try to write the code for plain HttpClient, to check, if there are other side-effects. Alternatively you can use PowerShell, like from this guy here: https://www.lieben.nu/liebensraum/2017/08/creating-a-dynamic-group-using-the-graph-api/

      Modified:
      $dynamicGroupProperties = @{
      “membershipRule” = “(user.userPrincipalName -notContains `”#EXT#@`”) -and (user.userType -ne `”Guest`”)”;
      “membershipRuleProcessingState” = “On”;
      }

      invoke-webrequest -Headers $headerParams -uri “https://graph.microsoft.com/beta/groups/{ID}” -Body (ConvertTo-Json $dynamicGroupProperties) -method PATCH -Verbose

  3. Greate post. Keep writing such kind of information on your blog.

    Im really impressed by it.
    Hey there, You have performed a great job. I’ll definitely digg it and personally suggest
    to my friends. I am sure they will be benefited from this site.

Leave a Reply to Thomas Tomow Cancel reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.