I’m looping through all groups to get group info and their members(users) info. The problem is the nested group members are being reported as just a member of the parent group. For example, user1 is a member of group2 and group2 is a member of group1. When I run this it just displays user1 and group1. How can I change this to show that user1 is a member of group2 and group2 is a member of group1?
foreach( $Group in $Groups ){
Get-ADGroupMember -Identity $Group -Recursive| Get-ADUser -Properties samaccountname, givenname,sn,title,description,mail,department,manager| foreach {
$data+= [pscustomobject]@{ObjectName =$_.name
objectclass =$_.objectclass
GroupName =$group.name
GroupCategory =$group.groupcategory
GroupScope =$group.groupscope
GroupDescription =$group.description
distinguishedName =$_.distinguishedName
UserName =$_.samaccountname
FirstName =$_.givenname
LastName =$_.sn
Title =$_.title
UserDescription =$_.Description
Email =$_.mail
Department =$_.department
Manager =$_.manager
}
}#end foreach
}# end foreach
Olaf
June 14, 2019, 5:17pm
2
There’s no easy/builtin way to achieve what you’re asking for. You’re using the parameter -Recursive. To achieve what you want you’d have to ommit the parameter -Recursive, check for each member of the queried group if it’s a group or not and if it’s a group “dive” into it and get the members. Please have in mind that’s it’s possible to have more than one level of nesting in your groups. So you might create a recursive function for that.
#Try this Script. This should work for you
$Groups = 'All_admins', 'AD-Grp-16'
$Consolidate = @()
foreach( $Group in $Groups ){
Get-ADGroupMember -Identity $Group -Recursive| Get-ADUser -Properties samaccountname, givenname,sn,title,description,mail,department,manager|
foreach {
$data= [pscustomobject]@{ObjectName =$_.name
objectclass =$_.objectclass
GroupName =$group.name
GroupCategory =$group.groupcategory
GroupScope =$group.groupscope
GroupDescription =$group.description
distinguishedName =$_.distinguishedName
UserName =$_.samaccountname
FirstName =$_.givenname
LastName =$_.sn
Title =$_.title
UserDescription =$_.Description
Email =$_.mail
Department =$_.department
Manager =$_.manager
}
$Consolidate+= $data
}
}#end foreach
$Consolidate
So this issue of getting AD group members including sub-groups has been on my mind for a while. I wrote a function to do just that. Example:
Install-Module AZSBTools -Force -AllowClobber
Get-SBADGroupMembers testgroup1
with output similar to:
Processing group CN=testgroup1,DC=TW24,DC=local
Processing child group CN=testgroup2,DC=TW24,DC=local (Parent: testgroup1)
UserName DN OU MemberOf
-------- -- -- --------
testuser1 CN=testuser1,DC=TW24,DC=local TW24 testgroup1
testuser2 CN=testuser2,DC=TW24,DC=local TW24 testgroup2.testgroup1
Try this…
function Get-ADNestedGroupMembers
{
[cmdletbinding()]
param
(
[String] $Group
)
Import-Module ActiveDirectory
($Members = Get-ADGroupMember -Identity $Group -Recursive)
}
Or this…
function Get-NestedGroupMember
{
[cmdletbinding()]
[Alias('gngm')]
param
(
[Parameter(Mandatory,ValueFromPipeline)]
[string]
$Identity
)
process
{
$user = Get-ADUser -Identity $Identity
$userdn = $user.DistinguishedName
$strFilter = "(member:1.2.840.113556.1.4.1941:=$userdn)"
Get-ADGroup -LDAPFilter $strFilter -ResultPageSize 1000
}
}
Or this…
$MasterGroup = "Denied RODC Password Replication Group"
$GlobalGroups = @()
$MemberGroups = @()
$MemberGroups += Get-ADGroupMember $MasterGroup |
where { $_.ObjectClass -eq "Group" }
Foreach ($MemberGroup in $MemberGroups)
{
IF ((Get-ADGroup $MemberGroup).GroupScope -eq "Global")
{ $GlobalGroups += $MemberGroup }
$NestedGroups = TRY
{
Get-ADGroup -Identity (Get-ADGroupMember $MemberGroup |
where { $_.ObjectClass -eq "Group" })
}
CATCH { }
$MemberGroups += $NestedGroups
$Membergroups = $MemberGroups -ne $MemberGroup
}