Monthly Archives: March 2024

Visualizing group hierarchy and membership – a new PowerShell module…

Groups allow administrators to organize users and contacts that share something in common. This may be a security group providing permissions or a distribution group providing a common email. Groups support any level of nesting allowing for a tree of groups with many branches. The depth and breadth that can be present in the hierarchy sometimes create challenges in locating members or understanding the scope of the group’s use. In addition to groups where membership is static, some groups support dynamic membership or the ability to add and remove users based off their attributes. This adds an additional layer of complexity when looking at group hierarchy and membership.

We often receive requests in support to assist in mapping out group membership. Customers may be preparing to migrate distribution lists from on-premises to Exchange Online and need to understand the parent / child relationship between groups. Other customers are investigating why a conditional access policy applied to a user, why a contact received an email addressed to a group, or who has access to a particular resource based on group membership. Answering these questions often requires an understanding of how groups and users are organized.

There have been several potential solutions to this inquiry. In Active Directory, administrators have access to a command get-adGroupMember -recursive. This command will walk a group hierarchy and provide information on the specific members that are discovered. The Get-ADGroupMember -recursive does an excellent job of highlighting the users that are discovered. Additional object classes, such as groups and contacts, are not displayed in the return. This limits the feasibility of such a command as a solution to this question.

PS C:\Repository\DLTestSuite> Get-ADGroupMember -Identity “A0-Group” -Recursive
distinguishedName : CN=C2-MailUserB,OU=DLHierarchy,DC=home,DC=domain,DC=com
name : C2-MailUserB
objectClass : user
objectGUID : 09779231-71e3-45bb-98ed-2f22be96f606
SamAccountName : C2MailuserB
SID : S-1-5-21-278042269-1514808692-1118015945-447265
distinguishedName : CN=C2-MailUserA,OU=DLHierarchy,DC=home,DC=domain,DC=com
name : C2-MailUserA
objectClass : user
objectGUID : 390d0f3e-502d-42a1-8d25-cdccdd497c6f
SamAccountName : C2MailuserA
SID : S-1-5-21-278042269-1514808692-1118015945-447264
distinguishedName : CN=C1-MailboxB,OU=DLHierarchy,DC=home,DC=domain,DC=com
name : C1-MailboxB
objectClass : user
objectGUID : 0081b0f0-ab04-4245-8049-35601dac51ef
SamAccountName : C1MailboxB
SID : S-1-5-21-278042269-1514808692-1118015945-447263

In Exchange Online get-distributionGroupMember will provide a list of all members of a group but does not operate recursively. The equivalent graph command get-MGGroupMember does the same but also does not operate recursively. This often requires additional work to determine the nested hierarchy and gather all potential objects included in scope.

In a synchronized directory users may reside in multiple locations. A user may reside in Active Directory, Entra ID, and Exchange Online. Although the same object is represented, each directory is independent, therefore an object may exist in one and not the other. This allows for the potential of group membership and hierarchy to be different depending on which directory is queried. Take the example of a parent group that has a child that is a dynamic distribution group. A dynamic distribution group is not replicated through Entra ID Connect, therefore the membership of the group in Active Directory is different than that of Entra ID or Exchange Online. You may also have differences as objects are intentionally excluded from synchronization. An example of this is a custom EntraID Connect rule that no longer synchronizes accounts that have been disabled. When disabling an account, it is present in all groups in Active Directory but subsequently would not be present in those same groups in EntraID or Exchange Online as the user is deleted when no longer synchronized.

DLHierarchy PowerShell Module

In the PowerShell Gallery is a new module, DLHierarchy. This PowerShell module allows administrators to query Active Directory, EntraID, or Exchange Online to build a complete group hierarchy and membership table. Administrators may select to have the hierarchy presented to them in text format, html format, or have both formats generated. In addition to handling static group membership, if enabled, a dynamic groups membership is expanded and included in the output. This allows for the most complete view of hierarchy and membership.

When the text option is enabled, a file is generated that contains a text-based tree. The tree contains the object display name, the unique object identifier from the directory queried, and any recipient type information that may be available. (Note: This information varies depending on the directory queried.)

Group Hierarchy for Group ID: 40bda585-832a-410a-a514-fdc443a9e877

A0-Group (ObjectGUID:40bda585-832a-410a-a514-fdc443a9e877) (group)

–B0-Group (ObjectGUID:cbab0378-84bd-4432-8ea6-910c1784af6a) (group)

—-C0-Group (ObjectGUID:81650155-3d68-4d26-b946-7960f72a4959) (group)

——C0 EquipmentMailbox (ObjectGUID:fcf71a4d-ad75-49d1-baff-ce081a18e1d4) (user)

——C0 RoomMaibox (ObjectGUID:4f4e0288-de33-402f-92b8-533fe4896ae9) (user)

——C0 ShareMailbox (ObjectGUID:855ab450-7d9c-4f13-bc09-ab8f65b84fac) (user)

—-C1-Group (ObjectGUID:b1b9823a-76d6-46ba-9f24-9f5b85450ac3) (group)

——C1 MailboxA (ObjectGUID:09c3a516-ee7e-4e0c-bdf7-f3b3add92e5e) (user)

——C1 MailboxB (ObjectGUID:0081b0f0-ab04-4245-8049-35601dac51ef) (user)

–B1-Group (ObjectGUID:3d434170-fa3a-4b40-ae08-ba823bfdccf5) (group)

—-C2-Group (ObjectGUID:96b01f6a-fb54-4c55-b294-fdaf0e2fc95a) (group)

——C2 MailUserA (ObjectGUID:390d0f3e-502d-42a1-8d25-cdccdd497c6f) (user)

——C2 MailUserB (ObjectGUID:09779231-71e3-45bb-98ed-2f22be96f606) (user)

—-C3-Group (ObjectGUID:d174ae4b-3df9-406c-8d04-0b91fd8c53d1) (group)

——C3MailContactA (ObjectGUID:8e6cf394-7661-452d-a0cf-b480e7b8f061) (contact)

——C3-MailContactB (ObjectGUID:fdea52a8-e067-4612-82ac-610e1a3afa5c) (contact)

——B1-Group (Circular Membership) (ObjectGUID:3d434170-fa3a-4b40-ae08-ba823bfdccf5) (group)

——D0-Dynamic (ObjectGUID:63e7cb1e-8cb6-41ad-bbf9-ab36d0a96b23) (msExchDynamicDistributionList)

——–D0-Group (ObjectGUID:d496c8c0-59b1-472c-b3c0-6e696f2f9f47) (group)

———-D0 MailboxC (ObjectGUID:ab01e00d-d87b-46c1-8ee4-2af3d17644b3) (user)

———-D0 MailboxD (ObjectGUID:0e35a8bb-3386-4ff8-9ff9-973177f932f2) (user)

——–D0 MailboxA (ObjectGUID:2fdbf8db-5738-4f31-8371-118e57a095cd) (user)

——–D0 MailboxB (ObjectGUID:be679478-96bc-4ecd-9ea1-57caab6924e0) (user)

——–D0 MailboxC (ObjectGUID:ab01e00d-d87b-46c1-8ee4-2af3d17644b3) (user)

——–D0 MailboxD (ObjectGUID:0e35a8bb-3386-4ff8-9ff9-973177f932f2) (user)

When the HTML option is enabled, an HTML file is automatically generated. The file is broken into three separate sections. The first section provides and interactive expandable tree outlining the group hierarchy and membership. Groups may be collapsed and expanded to walk the tree.

clip_image002

The second section lists a table of all unique objects discovered during the query. The table provides basic object information and a search function. The search function can be utilized to filter the table and locate a specific object.

clip_image004

The last section provides a visual representation of the object classes within the group queried. This section contains three sub-sections. The first sub-section shows the breakdown of groups contained within the parent group, the second sub-section shows the object classes for users or contacts contained within the group, and the last sub-section shows a total summary of all object classes within the group. This provides a quick visual representation of the types of objects contained within the group.

clip_image006

The default parameter set expands group membership and dynamic group membership for any group that is encountered. Optionally administrators may disable either of these operations. This allows flexibility to obtain the simple hierarchy without expanding the actual members of any group. This also cuts down on the overall time it takes to enumerate the group and member hierarchy.

clip_image008

Using the DLHierarchy PowerShell Module

The DLHierarchy PowerShell module contains three commands:

· Get-DLHierarchyFromGraph

· Get-DLHierarchyFromLDAP

· Get-DLHierarchyFromExchangeOnline

As the name of each function would suggest, this is the directory that is utilized to source.

When a client or server is identified to run the module the Remote Server Administration Tools for Active Directory must be installed. The module may be installed from the PowerShell gallery using Install-Module DLHierarchy.

Get-DLHierarchyFromLDAP

This function allows group collection from Active Directory. The user executing the command must have the permission to read all properties associated with groups and members.

To obtain the group object ID required for the command run get-ADGroup -identity NAME and note the objectGUID supplied in the output.

Get-ADGroup A0-Group

DistinguishedName : CN=A0-Group,OU=DLHierarchy,DC=home,DC=domain,DC=com

GroupCategory : Security

GroupScope : Universal

Name : A0-Group

ObjectClass : group

ObjectGUID : 40bda585-832a-410a-a514-fdc443a9e877

SamAccountName : A0-Group

SID : S-1-5-21-278042269-1514808692-1118015945-447253

Required Parameters:

· -GlobalCatalogServer which is the global catalog to perform the discovery operation.

· -GroupObjectID which is the objectGUID from Active Directory for the group.

· -LogFolderPath which is path where the log files and output files will be stored.

Optional Parameters:

· -ActiveDirectoryCredential a pre-gathered psCredential object. For example, $activeDirectoryCredential = get-credential. When a credential is not specified the user will be interactively prompted.

· -AllowTelemetryCollection which when enabled allows telemetry collection from the command.

· -ExpandGroupMembership which when enabled provides details not only regarding the group hierarchy but also the members contained within the group.

· -ExpandDynamicGroupMembership which when enabled if a dynamic group is discovered the recipient filter is expanded and the individual users included in the hierarchy report.

· -EnableTextOutput which when set to true includes text-based output for the group hierarchy in the log file directory.

· -EnableHTMLOutput which when set to true includes HTML based output for the group hierarchy in the log file directory.

Sample Commands:

· Get-DLHierarchyFromLDAP -groupObjectID 40bda585-832a-410a-a514-fdc443a9e877 -globalCatalogServer gc.domain.com -logFolderPath c:\temp

o This command prompts the user for interactive credentials and creates a hierarchy report for the provided objectID.

· Get-DLHierarchyFromLDAP -groupObjectID 40bda585-832a-410a-a514-fdc443a9e877 -globalCatalogServer gc.domain.com -activeDirectoryCredential $cred -logFolderPath c:\temp

o This command prompts the user for interactive credentials and creates a hierarchy report for the provided objectID.

· Get-DLHierarchyFromLDAP -groupObjectID 40bda585-832a-410a-a514-fdc443a9e877 -globalCatalogServer gc.domain.com -activeDirectoryCredential $cred -logFolderPath c:\temp -enableDynamicGroupMembership $FALSE -enableGroupMembership:$FALSE

o This command prompts the user for interactive credentials and creates a hierarchy report for the provided objectID that includes only groups.

Get-DLHierarchyFromGraph

This function allows group collection from EntraID utilizing Microsoft Graph. The following graph commands are utilized as a part of this collection.

Get-MGUser

Get-MgUser (Microsoft.Graph.Users) | Microsoft Learn

Get-MGGroup

Get-MgGroup (Microsoft.Graph.Groups) | Microsoft Learn

Get-MGGroupMember

Get-MgGroupMember (Microsoft.Graph.Groups) | Microsoft Learn

This command is currently set to require the scope Directory.Read.All. The command supports both interactive user authentication and certificate-based authentication. It is recommended to manually establish the connection using the credentials and specifying that the scope is available and consented to prior to executing the command.

·Certificate Authentication

Connect-MGGraph -scopes “Directory.Read.All” -clientID ID -tenantID ID -certificateThumbPrint thumbprint

Interactive Authentication

Connect-MGGraph -scopes “Directory.Read.All”

If the permissions are not currently assigned to the application registration or user credentials supplied, you will be prompted to consent to the necessary credentials. This may require additional administrator approval or interaction.

For a good reference on establishing certificate authentication, application registrations, and graph integration refer to: Using Certificate-based Authentication with the Microsoft Graph PowerShell SDK | Practical365

To obtain the group object ID utilize the get-MGGroup command and reference the ID attribute.

PS C:\> Get-MgGroup -filter “displayname eq ‘A0-Group'”

DisplayName Id MailNickname Description GroupTypes

———– — ———— ———– ———-

A0-Group 199c0b78-34f5-41d1-a9c7-40a173dfeee8 A0-Group {}

Required Parameters:

· -GroupObjectID which is the objectGUID from Active Directory for the group.

· -msGraphTenantID which is tenant ID associated with the EntraID instance hosting the group and users.

· -LogFolderPath which is path where the log files and output files will be stored.

Optional Parameters:

· -msGraphEnvironmentName when specified determines the cloud instance for graph connections.

· -msGraphCertificateThumbprint is required for certificate authentication and specifies the certificate thumbprint in the user certificate store that matches the certificate enabled on the EntraID application registration.

· -msGraphApplicationID is required for certificate authentication and specifies the EntraID application registration that has the required graph permissions enabled.

· -AllowTelemetryCollection which when enabled allows telemetry collection from the command.

· -ExpandGroupMembership which when enabled provides details not only regarding the group hierarchy but also the members contained within the group.

· -ExpandDynamicGroupMembership is not utilized with MS Graph based groups.

· -EnableTextOutput which when set to true includes text-based output for the group hierarchy in the log file directory.

· -EnableHTMLOutput which when set to true includes HTML based output for the group hierarchy in the log file directory.

Sample Commands:

· Get-DLHierarchyFromGraph -groupObjectID 199c0b78-34f5-41d1-a9c7-40a173dfeee8 -logFolderPath c:\temp -msGraphTenantID “TenantID”

o This command prompts the user for interactive credentials and creates a hierarchy report for the provided objectID.

· Get-DLHierarchyFromgGraph -groupObjectID 40bda585-832a-410a-a514-fdc443a9e877 -msGraphTeanantID “TenantID” -msGraphCertificateThumbprint “Thumbprint” -msGraphApplicationID “ApplicationID” -logFolderPath c:\temp

o This command utilizes certificate authentication credentials and creates a hierarchy report for the provided objectID.

· Get-DLHierarchyFromgGraph -groupObjectID 40bda585-832a-410a-a514-fdc443a9e877 -msGraphTeanantID “TenantID” -msGraphCertificateThumbprint “Thumbprint” -msGraphApplicationID “ApplicationID” -logFolderPath c:\temp -enableGroupMembership:$FALSE

o This command utilizes certificate authentication credentials and creates a hierarchy report for the provided objectID that includes groups only.

Get-DLHierarchyFromExchangeOnline

This function allows group collection from Exchange Online using Exchange Online Powershell. The following Exchange Online commands are utilized as part of this collection.

Get-Group

Get-Group (ExchangePowerShell) | Microsoft Learn

Get-User

Get-User (ExchangePowerShell) | Microsoft Learn

Get-DistributionGroup

Get-DistributionGroup (ExchangePowerShell) | Microsoft Learn

Get-DistributionGroupMember

Get-DynamicDistributionGroupMember (ExchangePowerShell) | Microsoft Learn

Get-DynamicDistributionGroup

Get-DynamicDistributionGroup (ExchangePowerShell) | Microsoft Learn

Get-UnifiedGroup

Get-UnifiedGroup (ExchangePowerShell) | Microsoft Learn

Get-Mailbox

Get-Mailbox (ExchangePowerShell) | Microsoft Learn

Get-MailUser

Get-MailUser (ExchangePowerShell) | Microsoft Learn

Get-Contact

Get-Contact (ExchangePowerShell) | Microsoft Learn

When utilizing interactive credentials, the user executing the function must be able to execute the prior commands and have a scope of all recipients objects included in the groups discovered. Alternatively, certificate authentication is available and may be utilized with the command. For references on establishing app only authentication to Exchange Online reference App-only authentication in Exchange Online PowerShell and Security & Compliance PowerShell | Microsoft Learn.

To obtain the group object ID utilize the get-recipient command and reference the ExchangeObjectID attribute.

PS C:\> Get-Recipient A0-Group | fl ExchangeObjectID

ExchangeObjectId : 84164328-d181-4654-819f-296302960a91

Required Parameters:

· -GroupObjectID which is the objectGUID from Active Directory for the group.

· -LogFolderPath which is path where the log files and output files will be stored.

Optional Parameters:

· -exchangeOnlineCredential when specified provides the stored credential for Exchange Online connection. Note: This does not support interactive authentication for multi-factor authentication.

· -exchangeOnlineCertificateThumbprint is required for certificate authentication and specifies the certificate thumbprint in the user certificate store that matches the certificate enabled on the EntraID application registration for Exchange Online app-based access permissions.

· -exchangeOnlineAppID is required for certificate authentication and specifies the EntraID application registration that has the required Exchange Online app-based access permissions.

· -exchangeOnlineOrganizationName is the domain.onmicrosoft.com name associated with the Exchange Online organization and is required for certificate authentication.

· -exchangeOnlineEnvironmentName is the environment name for Exchange Online PowerShell connections when not utilizing a commercial tenant.

· -AllowTelemetryCollection which when enabled allows telemetry collection from the command.

· -ExpandGroupMembership which when enabled provides details not only regarding the group hierarchy but also the members contained within the group.

· -ExpandDynamicGroupMembership is not utilized with MS Graph based groups.

· -EnableTextOutput which when set to true includes text-based output for the group hierarchy in the log file directory.

· -EnableHTMLOutput which when set to true includes HTML based output for the group hierarchy in the log file directory.

Sample Commands:

· Get-DLHierarchyFromExchangeOnline -groupObjectID 84164328-d181-4654-819f-296302960a91 -logFolderPath c:\temp

o This command prompts the user for interactive credentials and creates a hierarchy report for the provided objectID. Interactive authentication with Multi-factor authentication is supported in this command.

· Get-DLHierarchyFromExchangeOnline -groupObjectID 84164328-d181-4654-819f-296302960a91 -exchangeOnlineCredential $cred -logFolderPath c:\temp

o This command utilizes credentials stored as a psCredential and creates a hierarchy report for the provided objectID.

· Get-DLHierarchyFromExchangeOnline -groupObjectID 84164328-d181-4654-819f-296302960a91 -exchangeOnlineOrganizationName “domain.onmicrosoft.com” -exchangeOnlineCertificateThumbprint “CertificateThumbprint” -exchangeOnlineAppID “ApplicationID” -logFolderPath c:\temp

o This command utilizes certificate authentication credentials and creates a hierarchy report for the provided objectID.

· Get-DLHierarchyFromExchangeOnline -groupObjectID 84164328-d181-4654-819f-296302960a91 -exchangeOnlineOrganizationName “domain.onmicrosoft.com” -exchangeOnlineCertificateThumbprint “CertificateThumbprint” -exchangeOnlineAppID “ApplicationID” -logFolderPath c:\temp -enableGroupMembership:$FALSE

o This command utilizes certificate authentication credentials and creates a hierarchy report for the provided objectID that includes groups only.