Create an “All managers” group in Microsoft 365

In this article, we will explore the different methods for creating a Microsoft 365 group, which includes all managers within your organization. Or maybe just the people managers. There are many different ways such a group can be created, and it’s more than likely that the solution provided here will not cater to your specific needs. But as with any other example posted on the blog, you should be able to quickly modify it to address any shortcomings.

What is a manager?

Let’s start with defining what a “manager” is. While the answer might be clear to you, or at least to the HR staff within your company, when it comes to finding an answer to this questions programmatically, opinions will vary. There is no single “this user is a manager” attribute that we can leverage within either Azure AD or on-premises AD. Instead, the usual approach is a “backwards” one – you designed a person as a manager by stamping his name on the Manager property for any of his subordinate user’s account. The examples below show how this would look like in Microsoft 365, by leveraging the various PowerShell cmdlets available within Office 365:

#Manager property in Exchange Online
C:\> Get-User gosho | select Name,manager

Name Manager
---- -------
gosho HuKu

#Manager property in Azure AD
C:\> Get-AzureADUserManager -ObjectId gosho@michev.info

Object DisplayName UserPrincipalName UserType
-------- ----------- ----------------- --------
e0d7442c-8cd8-4e65-8ede-ec9887816677 HuKu HuKu@michev.onmicrosoft.com Member

#Manager property in Azure AD via the Graph API cmdlets
C:\> Get-MgUser -UserId gosho@michev.info | select DisplayName,@{n="Manager";e={(Get-MgUserManager -UserId $_.Id).Id}}

DisplayName Manager
----------- -------
Gosho e0d7442c-8cd8-4e65-8ede-ec9887816677

#Or a proper, human-readable variation of the above
C:\> Get-MgUser -UserId gosho@michev.info | select userPrincipalName,@{n="Manager";e={(Get-MgUserManager -UserId $_.Id).AdditionalProperties.userPrincipalName}}

UserPrincipalName Manager
----------------- -------
gosho@michev.info HuKu@michev.onmicrosoft.com

While this tells us who the manager is for a given user, it does not directly help us solve the original task. Sure, one can enumerate all users and capture any and all values under the “manager” property, but that’s hardly a good approach. Instead, we can take a look at the “backlink” sister property of “manager”, namely the DirectReports one. If manager gives us a pointer to the user’s manager, the DirectReports property gives us a list of all users that “report” to the given user, in other words it tells us that the given user is a manager for all the returned objects. Let’s see how it looks like in practice:

#DirectReports property in Exchange Online
C:\> Get-User huku | select Name,manager,DirectReports

Name Manager DirectReports
---- ------- -------------
HuKu {gosho, shared, vasil}

#DirectReports property in Azure AD
C:\> Get-AzureADUserDirectReport -ObjectId huku@michev.onmicrosoft.com

ObjectId DisplayName UserPrincipalName UserType
-------- ----------- ----------------- --------
584b2b38-888c-4b85-8871-c9766cb4791b Vasil Michev vasil@michev.info Member
cb38f772-b77e-47d2-a45c-efb7bd0a175e shared shared@michev.info Member
064abb3c-0812-44f9-bdcc-eea7e6ea398b Gosho gosho@michev.info Member

#directReports property in Azure AD via the Graph API cmdlets
C:\> Get-MgUserDirectReport -UserId huku@michev.onmicrosoft.com

Id DeletedDateTime
-- ---------------
584b2b38-888c-4b85-8871-c9766cb4791b
cb38f772-b77e-47d2-a45c-efb7bd0a175e
064abb3c-0812-44f9-bdcc-eea7e6ea398b

#Or a proper, human-readable variation of the above
C:\> Get-MgUserDirectReport -UserId huku@michev.onmicrosoft.com | select @{n="DisplayName";e={$_.AdditionalProperties.displayName}},@{n="UserPrincipalName";e={$_.AdditionalProperties.userPrincipalName}}

DisplayName UserPrincipalName
----------- -----------------
Vasil Michev vasil@michev.info
shared shared@michev.info
Gosho gosho@michev.info

The information presented above should in turn match what we see in the user’s profile card in Outlook, or the Address book entry. Similarly, Microsoft Teams will show the same under the user’s profile card or the Organization chart, but keep in mind that Teams will show only users that are “known” to the service, i.e. those with corresponding licenses, and enabled in Azure AD. Thus, the number of direct reports might actually vary, depending on where you look.

AllManagers1

AllManagers2

Thus, for our purposes, it should be sufficient to list all the users that have at least one value returned under the DirectReports property.

Create an All managers dynamic distribution group

After this lengthy introduction, let’s see how we can go about creating an All managers group. Let’s start with the Exchange Online scenario, which is usually the easiest one to handle. And the cheapest, as we can create Dynamic Distribution Groups without the need for any additional licenses. Moreover, as the primary role of an All managers group will likely be to facilitate communication with all the members, a distribution group seems like a natural choice.

Luckily, the DirectReports property is a supported property for OPATH queries via the –Filter/-RecipientFilter parameter, so we can use it to create a new Dynamic Distribution Group. Even better, the property supports comparison operators against $null, which in turn enables us to create a simple query that will give us a list of all user with at least one direct report. Here’s an example:

#Return all user objects with at least one direct report
C:\> Get-User -Filter {DirectReports -ne $null}

#Return all recipient objects with at least one direct report
C:\> Get-Recipient -RecipientPreviewFilter {DirectReports -ne $null}

#Create an "All managers" dynamic distribution group
C:\> New-DynamicDistributionGroup "All managers" -RecipientFilter {DirectReports -ne $null}

And that’s it. The newly provisioned All managers dynamic distribution group can now be used to address all the managers within your organization. As usual in such scenarios, you might want to restrict who can send messages to the group, by leveraging the –AcceptMessagesOnlyFromSendersOrMembers parameter. Similarly, you might want to hide it from the GAL by toggling –HiddenFromAddressListsEnabled.

Set-DynamicDistributionGroup "All managers" -AcceptMessagesOnlyFromSendersOrMembers @{add="HR","CEO","Leadership team"} -HiddenFromAddressListsEnabled:$true

Create an All managers Microsoft 365 Group

While Dynamic Distribution Groups are a simple and cheap solution to the task at hand, chances are you might want to use the All managers group for more than sending messages or scheduling meetings. Having a space to share documents with members of the group or provisioning a bunch of additional applications is something that can easily be enabled by leveraging a Teams-enabled group. Thus, let’s examine the scenario where our All managers group is powered by an Microsoft 365 on the backend.

As membership of a dynamic Microsoft 365 Group is governed by queries against Azure AD instead of Exchange Online’s directory, few issues arise. First, and most important, is the lack of proper support for the DirectReports property. While the property exists in Azure AD and can be queried via the Graph API, it is not possible to filter against it. Even with advanced query filters, a server-side filter based on DirecrReports is a no go. And while we don’t even need to know the full list of objects returned via said property, but only filter against their count (via the $count operator, much like in this example), the current state of the Graph API prevents us from addressing this scenario.

Microsoft has tried to address this limitation of the Graph API by providing us with a pre-canned query we can use as a membership rule, namely the direct reports for “guid” one, as detailed here. Unfortunately, said query can only be used against a given object, as specified by the GUID, and cannot be combined by any other operator or query. In other words, we cannot use it to address the requirements for our group.

Thus, instead of using a dynamic membership rule, we will have to stick to a static group membership list. On the positive side, this approach addresses the other issue with dynamic membership rules in Azure AD, namely the requirement for Azure AD Premium license. Another positive is that we can still use the Exchange Online queries to get the desired list of users, then either add them directly as a member of a Microsoft 365 Group or populate a property that we can later use in a dynamic query. Let’s examine both scenarios.

In both cases, we will have to create the Microsoft 365 Group beforehand. Any of the available methods/endpoints would do, but if you plan to use dynamic membership for the group, it’s probably best to create it via the Azure AD blade or the Graph API. Once the group is created, we can use the below to manually populate its membership:

#Obtain a list of all managers
C:\> $users = Get-User -Filter {DirectReports -ne $null}

#(optional) Configure a custom property for each user returned above
C:\> $users | % { Set-Mailbox $_.ExternalDirectoryObjectId -CustomAttribute7 "IsManager"}

#Add all the returned users as members of our All Managers Microsoft 365 Group
C:\> $users | % { Add-UnifiedGroupLinks "All Managers" -LinkType member -Links $_.ExternalDirectoryObjectId}

Alternatively, you can skip the last cmdlet and opt to use dynamic membership for the Microsoft 365 Group. In that case, head to the Azure AD blade, open the Group properties page and under Dynamic membership rules, enter something like:

(user.extensionAttribute7 -eq "IsManager")

where we’re leveraging the fact that Exchange’s set of customattributeXX is exposed via the extensionAttributeXX collection. Some caveats apply to how you can configure said attributes, but for the purposes of this article it’s sufficient to know that it is possible.

Whichever way you choose to provision membership for the All Managers Microsoft 365 Group, you likely want to restrict visibility and enforce some delivery restrictions. As with the previous scenario, we can use the Exchange Online cmdlets:

Set-UnifiedGroupLinks "All managers" -AcceptMessagesOnlyFromSendersOrMembers @{add="HR","CEO","Leadership team"} -HiddenFromAddressListsEnabled:$true

Create an All managers Azure AD Security group

Instead of leveraging the All managers group for communication and collaboration between all the managers within the organization, in some cases you might want to use it to delegate access to certain functionalities and roles, or assign licenses to the group’s members. An Azure AD security group should be a better choice to address such scenarios, or as a corner case you might want to combine both and use a security-enabled Microsoft 365 Group.

This scenarios is very similar to the above one, as Azure AD security groups support the same membership controls as Microsoft 365 Groups. As before, a purely dynamic membership solution will not be possible, so you either provision and maintain the membership as a static list, or use workarounds such as creating a dynamic rule based on one of the extensionAttributeXX. Refer to the examples in the previous section.

Summary

In this article, we explored the idea of creating an All managers group within Microsoft 365, such that it includes all (people) managers within the organization. Once such a group has been created, you can use it to easily communicate with all the managers, organize meetings, share files or even provision certain functionalities, based on the list of members. Ideally, you would want to use a group with dynamic membership, so you don’t have to constantly add or remove members, however this is only possible for pure Exchange groups, or more specifically Dynamic Distribution Groups.

Hopefully in the future, the Graph API will mature enough to allow us to address such scenarios via dynamic membership rules in Azure AD, which in turn will open the door for more possibilities. Should this happen, I will make sure to update this article with the relevant details.

Whatever the solution is however, do make sure to keep your AD/Azure AD users and their attributes up to date, as any dynamic solution is only as good as the data it relies on. If a dynamic solution based on the Manager/Direct reports relationship is not possible, you can leverage other attributes, such as customAttributeXX or even Title, but again – the solution will be as good as the data you feed it.

5 thoughts on “Create an “All managers” group in Microsoft 365

  1. Steve says:

    Any idea on how to create a dynamic group that pulls all folks that report to a VP? So on prem today we can do this with an ldap query that uses LDAP_MATCHING_RULE_IN_CHAIN (manager:1.2.840.113556.1.4.1941) but I cannot find any way to make this work in Entra or Exchange online powershell. Even though I can filter on it it will not create the group due to the syntax. It seems the only way to do it in Entra is by nesting direct report groups for each mgr.

    $filter= ‘(manager:1.2.840.113556.1.4.1941:=CN=user1,OU=domain.onmicrosoft.com,OU=Microsoft Exchange Hosted Organizations,DC=NAMPR06A002,DC=prod,DC=outlook,DC=com)’

    Get-Recipient -RecipientPreviewFilter $Filter -ResultSize unlimited | select disp*

    DisplayName
    ———–
    Lab Test 04
    Shawn
    steve03
    steve05
    steve08
    steve09
    steve10
    steve11

    New-DynamicDistributionGroup -Name “GroupOne” -alias “GroupOne” -RecipientFilter $filter -WhatIf
    Write-ErrorMessage : Cannot process argument transformation on parameter ‘RecipientFilter’. Cannot convert value
    “(manager:1.2.840.113556.1.4.1941:=CN=User,OU=domain.onmicrosoft.com,OU=Microsoft Exchange Hosted
    Organizations,DC=NAMPR06A002,DC=prod,DC=outlook,DC=com)” to type “System.String”. Error: “Invalid filter syntax. For a description of
    the filter parameter syntax see the command help.
    “(manager:1.2.840.113556.1.4.1941:=CN=user,OU=domain.onmicrosoft.com,OU=Microsoft Exchange Hosted
    Organizations,DC=NAMPR06A002,DC=prod,DC=outlook,DC=com)” at position 10.”
    At C:\Users\stevem\AppData\Local\Temp\tmpEXO_dvc1mtxb.v2y\tmpEXO_dvc1mtxb.v2y.psm1:1204 char:13
    + Write-ErrorMessage $ErrorObject
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : NotSpecified: (:) [New-DynamicDistributionGroup], ParameterTransformationException
    + FullyQualifiedErrorId : [Server=MWHPR06MB3263,RequestId=ce82c8d5-1932-b51c-99cc-3fba5b363746,TimeStamp=Fri, 06 Sep 2024 17:59:0
    7 GMT],Write-ErrorMessage

    Reply
    1. Vasil Michev says:

      Afaik there is no way to achieve something like that in Exchange Online/Entra ID. You can use the filter to stamp each recipient’s customattributeXX with some value and create a rule based on that, or use nested groups as you mentioned above.

      Reply
  2. Stan says:

    Any tips on how to create an “All Reports” distribution list for each of the managers?

    Reply

Leave a 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.