Sunday, June 2, 2013

Export AD group members - nested / recursive group members

Hi Readers,

As my love for powershell is growing so is my repository of scripts.

This script that I have written has been requested by various community members & by front facing Teams in our organization.

By using this script you have to just in put CN of a group (otherwise it will not work) & it will recurse thru to extract the group members

from all the nested group. (machine from which you are running it must have "ADSI Edit"--this is part of administration tools)

Just paste the script in any folder, run getmembers.bat



It will ask you to enter group CN



After you enter the name it will loop thru the group & extract the information in the form of text files in same folder.

uniquemembers is the list of users that are part of the group & unique group is the name of groups that are nested.(including the main group)




PowerShell

##################################################################################  
#       Author: Vikas Sukhija  
#       Date: 06/31/2013  
#       Description: Extract group members recursevely  
###################################################################################  

$Group = Read-Host "Enter the group CN name"  

######################check if object is group or not ############################# 
function checkgroup ($Group1) 


$Search = New-Object DirectoryServices.DirectorySearcher([ADSI]"") 
$Search.filter = "(&(objectCategory=group)(objectClass=group)(cn=$Group1))" 
$input=$Search.Findall() 

if($input -ne $null) 

##Write-Host "$Group1 is a valid" 
return $true 

else  

##Write-Host "$Group1 is a invalid" 
return $false 


##################################Recurse thru groups ############################## 

function getallmembersrecursively ($Group)  
{  
$Search = New-Object DirectoryServices.DirectorySearcher([ADSI]"")  
$Search.filter = "(&(objectCategory=group)(objectClass=group)(cn=$Group))"  
$input=$Search.Findall()  

if($input -ne $null)  
{  
Foreach($group in $input){  
$groupname = $group.GetDirectoryEntry()  
$GPName = $groupname.DistinguishedName  
$GPMember = $groupname.member  
$GPName1 = [string]$GPName  
$gsplit1 = $GPName1.split(",")  
$fpiece1 = $gsplit1[0]  
$cnsplit1 = $fpiece1.split("=")  
$GPName2 = $cnsplit1[1]  

Write-Host "$GPName2 is a Group"  
Add-Content .\groups.txt $GPName2  

####get all groups from file to compare so as there is no circular nesting 

$getallgroups = Get-Content .\groups.txt 

Foreach($gmember in $GPMember){  
$gsplit = $gmember.split(",")  
$fpiece = $gsplit[0]  
$cnsplit = $fpiece.split("=")  
$Name = $cnsplit[1]  

$result = checkgroup $Name 

if ($result -eq "true") 

    if ($getallgroups -contains $Name) 
        { 
            Write-Host "$Name equals $GPName2" 
            #####not needed for troubleshooting######Add-Content .\conflict.txt "$Name equals $getallgroups -----"   

        } 
    else  
        { 
            #####not needed for troubleshooting######Add-Content .\donotconflict.txt "$Name recurse" 
            getallmembersrecursively $Name 
        } 


else 

Write-Host $Name 
Add-Content .\members.txt $Name  
##############Write-Host "$Name not equals $GPName2" 

}  
}  
}  
}  

####################################################################### 
getallmembersrecursively $Group  
sleep 5  
#########################unique members################################  

$uniquemembers = Get-Content .\members.txt  
$uniquemembers = $uniquemembers | select -uniq  
Add-Content .\uniquemembers.txt $uniquemembers  

$uniquegroups = Get-Content .\groups.txt  
$uniquegroups = $uniquegroups | select -uniq  
Add-Content .\uniquegroups.txt $uniquegroups  

#######################################################################




updated to handle looping of nested groups...
 Note:- don't forget to delete the output files if the script has been run previously.




------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


There is one more method for doing this task without this lengthy script, If you use Quest management AD shell. (Free Shell, thanks to Quest)




Just use below command line if you have Quest shell installed.


Get-QADGroupMember "group name"  -Indirect  (you can pipe the output to text file by using > )


 

Regards

Sukhija Vikas

15 comments:

  1. amazing script! However, i am having trouble with getting all the members of my groups. for instance, the result does not have some users. I confirm this by checking the last few names starting with Z. Is there a limit to this? it seems random where some names are not showing on the list. let me know. thank you!!!

    ReplyDelete
  2. by the way the group i am querying does not have any nested groups in there.

    ReplyDelete
  3. Strange , I have tested it many times without issues. I will definitely check & get back to you.

    ReplyDelete
  4. For the time being, have you tried another simple method in the blog
    Get-QADGroupMember “group name” -Indirect

    ReplyDelete
  5. yeah.i've tried that but too much overhead on the RAM(LOL). I like your script and feel comfortable giving it to my guys to use it for monthly reporting. btw, i'm talking about exporting over 13K users..still i dont think that would be a problem, right?

    ReplyDelete
  6. Ok, let me get back after testing with big list. As I remember there is an internal limit of AD that can be overcome. Let me check as I had tested it for few thousand members & it worked fine in the past.

    ReplyDelete
  7. so i tested another group and noticed the same issue. they both reach up to 15K and stops-wierd thing is, it exports users starting with letters A - Z, but within each, it only pulls some not necessarily all A's to whatever letter when it reaches 15 rows.

    ReplyDelete
  8. Still didn't got any time to check but if you have tried dsget command ??
    dsget group "CN=Backup Operators,OU=Test,DC=Contoso,DC=Com" -members -expand
    http://technet.microsoft.com/en-us/library/cc731202(v=ws.10).aspx

    ReplyDelete
  9. Hi There

    I left a message for you on the Microsoft website where your scrip is hosted. Nice Job again btw.

    I need to extract the nested groups of multiple groups that are in a text file. Can the script be modifed to query each group in the text file and output the nested groups for each group in the list with it's own output file named as the group that was queried?

    Thanks.

    ReplyDelete
  10. I will modify the script, give me some time..

    ReplyDelete
  11. Holiday time, So was not able to work on it..I will try this week to get some time devoted to this.

    ReplyDelete
  12. I have created the script, you can get it from below location:
    http://gallery.technet.microsoft.com/Export-AD-group-members-e89f3457

    ReplyDelete
  13. It is Still not Pulling all the Users, i have 90000 users and only 48000 users are listed, when check i have the nested Group but the user is missing. there.

    ReplyDelete
  14. Try the quest one, if you haven’t tried already
    Export AD group members – nested / recursive group members using Quest:

    http://gallery.technet.microsoft.com/Export-AD-group-members-257002b5
    Reply

    ReplyDelete