If you’ve ever been caught in a web of group membership management and felt like you’d reached your breaking point, you’re not alone. Group membership management is a major Active Directory management challenge on multiple grounds. Permissions are most often messed up, security is on the verge of being compromised, and not to mention auditing gone all haywire.
This blog will help you untangle yourself from the mess of nested group membership. First things first, you can use this complex yet useful PowerShell script to get things straightened out in no time.
function Get-UserGroupMembershipRecursive { [CmdletBinding()] param( [Parameter(Mandatory = $true, ValueFromPipeline = $true)] [String[]]$UserName ) begin { # introduce two lookup hashtables. First will contain cached AD groups, # second will contain user groups. We will reuse it for each user. # format: Key = group distinguished name, Value = ADGroup object $ADGroupCache = @{} $UserGroups = @{} # define recursive function to recursively process groups. function __findPath ([string]$currentGroup) { Write-Verbose "Processing group: $currentGroup" # we must do processing only if the group is not already processed. # otherwise we will get an infinity loop if (!$UserGroups.ContainsKey($currentGroup)) { # retrieve group object, either, from cache (if is already cached) # or from Active Directory $groupObject = if ($ADGroupCache.ContainsKey($currentGroup)) { Write-Verbose "Found group in cache: $currentGroup" $ADGroupCache[$currentGroup] } else { Write-Verbose "Group: $currentGroup is not presented in cache. Retrieve and cache." $g = Get-ADGroup -Identity $currentGroup -Property "MemberOf" # immediately add group to local cache: $ADGroupCache.Add($g.DistinguishedName, $g) $g } # add current group to user groups $UserGroups.Add($currentGroup, $groupObject) Write-Verbose "Member of: $currentGroup" foreach ($p in $groupObject.MemberOf) { __findPath $p } } else {Write-Verbose "Closed walk or duplicate on '$currentGroup'. Skipping."} } } process { foreach ($user in $UserName) { Write-Verbose "========== $user ==========" # clear group membership prior to each user processing $UserObject = Get-ADUser -Identity $user -Property "MemberOf" $UserObject.MemberOf | ForEach-Object {__findPath $_} New-Object psobject -Property @{ UserName = $UserObject.Name; MemberOf = $UserGroups.Values | % {$_}; # groups are added in no particular order } $UserGroups.Clear() } } }
You can also use Active Directory Users and Computers (ADUC) to add users/members to a group, but there is no easy and straightforward way to determine what groups these users will truly be a member of (Figure 1). With ADUC, there’s no way to see a child group’s parent group. The recursion function, a part of the AD PowerShell Script shared above, allows you to specify a group and then find all the users in that group.
For those of you who don’t have time for tedious and complex PowerShell scripting, prepare to draw power from the best of the best when it comes to Active Directory reporting and management, ADManager Plus.
With the built-in recursive group membership report, retrieve both the direct group memberships and indirect/nested group memberships in just two clicks (Figure 2).
As a bonus tip, check out these best practices while creating groups:
Create Role-based groups and name them logically to identify and administer groups more effectively. For instance, you can name your group Gl_Fiance_FC to stand for GlobalGroup_FinanceDepartment_Full control. It’s crucial to ideate and instate a group naming convention and ensure it’s followed with tremendous rigor. Post-implementation, you’ll be able to identify the group type and intentions just by looking at the name of the group. You will also get instant clarity on group nesting as a benefit of adopting this naming strategy.
For group nesting, one would want to follow the industry best practice commonly referred to as IGDLA (identities, global groups, domain local groups, and access).
Layer 1. Identities (user and computer accounts) are members of:
Layer 2: Global groups that represent business roles. Those role groups (global groups) are members of:
Layer 3: Domain local groups that represent management rules—determining who has read permission to a specific collection of folders, for example. These rule groups (domain local groups) are granted:
Layer 4: Access to resources. Access is granted to a shared folder by adding the domain local group to a folder’s access control list (ACL), with appropriate permissions that provide the right level of access.
I’m confident that you will be able to wrangle Active Directory group reporting and management using our tool. Try ADManager Plus.