exporting AD group membership of Mutliple user to csv or text.

This topic contains 2 replies, has 3 voices, and was last updated by  L-Bo 1 year, 9 months ago.

  • Author
  • #38460


    Hello All,
    I was wondering how to use PowerShell script export AD group membership of multiple users to CSV or text file than delete them from all groups excluding primary groups. Any help would be greatly appreciated.

    I am looking for something that would give me list of all groups User A, than All groups of User B, and so on. If my question unclear please let me know


  • #40672

    Geoff Duke

    Kivi, you'll want to use a couple cmdlets from the Active Directory module. In particular, the Get-ADPrincipalGroupMembership cmdlet is key to getting the groups of which a particular user (or group) is a member.

    Since your task is potentially destructive, I would approach it in two parts. First, generate the group membership list, and confirm that you are getting accurate data. Then perform the group membership removal as a subsequent step, which should be reversible if your exported data from the previous step is valid.

    Presuming that you have a text file that contains a few usernames (samaccountnames), one per line, something like this might work. Please don't just run this code! It's mean as a place to start. I didn't write a whole script with error handling and warning about the potential to blow away all group membership in your organization.

    # Part 1 - Generate a CSV file first, with format like:
    # "userX","CN=Example User,CN=Users,DC=contoso,DC=com","Accounting","CN=Accounting,CN=Users,DC=contoso,DC=com","FALSE"
    Get-Content -path 'C:\temp\UserList.txt' | foreach {
        $User   = Get-ADUser $_ -Properties PrimaryGroup
        $Groups = Get-ADPrincipalGroupMembership $User
        Foreach ($group in $Groups) {
            $Props = @{
    	        UserID  = $User.SAMAccountName
    	        UserDN  = $User.DistinguishedName
    	        GroupID = $group.SamAccountName
    	        GroupDN = $group.DistinguishedName
    	        IsUserPrimaryGroup = ( $group.DistinguishedName -eq $User.PrimaryGroup )
            # One CSV line for each user/group 
            New-Object PSObject -Property $Props
    } | Export-Csv -Path 'C:\temp\UserGroups.csv' -NoTypeInfo
    # Part 2 - Remove the users from all but the Primary Group (and Domain Users)
    Import-Csv C:\temp\UserGroups.csv | Where IsUserPrimaryGroup -eq $false | 
        Where GroupID -ne 'Domain Users' | Foreach {
            Write-Verbose "Removing '$($_.UserID)' from '$($_.GroupID)'"
            Remove-ADGroupMember $_.GroupDN -Members $_.UserDN -confirm:$false

    If you have many users to process, there are ways to optimize the code to prevent having to make a call for each group removal. you can Remove a list of groups from a single user, or a list of users from a single group, as one operation.

    I hope that's helpful.

  • #41147


    I wrote this function for myself because I do this at work quite often. This function is only good for a single user, but can easily be modified to accept multiple strings in the parameter.

    Function Get-ADUMemberOf{
    < #
      Retrieves group membership for target user object
      Retrieves group membership for a target user object. Has the ability to capture group membership to a list, then attempt to remove all groups
      writing each failed group to $Report2 
      $Report1 - Log file of existing group memberships stored in C:\scripts\reports\Memberof__Before.txt
      $Report2 - Log file remaining group memberships stored in C:\scripts\reports\MemberOf__After.txt
      Version:        2.2
      Author:         Logan "L-Bo" Boydell
      Creation Date:  03/03/2016
      v2.0 - Put into proper format, changed $Group variable to contain the values from the "SamAccountName" attribute instead of
             the name attribute. This eliminates the "Not Found" issue when the name doesn't match the SamAccountName when using 
             the -remove parameter
      v2.1 - Modified specifically for Transfer Script to integrate with Get-COMPANYADGroupPermission function for added usability
             # Start-Sleep -Seconds 2
             # Start-Process  notepad -ArgumentList "$Report2"
      v2.2 - Used "Set-Variable" cmdlet with "-Scope" parameter, value set to "Script". This creates variables that are available 
             during the execution of the script. ($Report2 is used in the proxy script to generate the final report)
      PS C:\Windows\system32> Get-ADUMemberOf -Identity Billy.User
      Outputs group memberships for AD User "Billy.User" to the console
      PS C:\Windows\system32> Get-ADUMemberof -Identity Jesse.Pinkman -Remove
      Creates "MemberOf_'Jesse.Pinkman'_BEFORE.txt", attempts to remove all the
      groups the user is a member of, then creates a "MemberOf_'Jesse.Pinkman'_AFTER.txt"
      for any groups that couldn't be removed
            # Param1 SamAccountName of AD User Object
                       HelpMessage="Enter SamAccountName of User Object",
         Set-Variable -Name "Path" -Value "C:\scripts\reports" -Scope Script
         Set-Variable -Name "Before" -Value "MemberOf_'$Identity'_BEFORE.txt" -Scope Script
         Set-Variable -Name "After" -Value "MemberOf_'$Identity'_AFTER.txt" -Scope Script
         Set-Variable -Name "Report1" -Value (Join-Path -Path $Path -ChildPath $Before) -Scope Script
         Set-Variable -Name "Report2" -Value (Join-Path -Path $Path -ChildPath $After) -Scope Script
         $DC = Get-ADDomainController | Select-Object -ExpandProperty HostName
         #Set-Variable -Name "DC" -Value (Get-ADDomainController | select -ExpandProperty HostName) -Scope Script
         Foreach($I in $Identity)
             $User = @()
             $Group = @()
             $User = Get-ADUser -Identity $I -Properties MemberOf -Server $DC
             $Group  = $User.Memberof | Get-ADGroup -Server $DC| Select-Object -ExpandProperty  samaccountname | Sort-Object
                If($Group -eq  $null) {Write-Warning "There are no group memberships to remove from $($User.name)"}
                Else # Export list of groups before any actions are taken
                 # Test if $Path exists, else make $Path
                 If(Test-Path $Path) {} 
                 Else {md $Path *>$null}
                 # Test if $Report1 exists, else make $Report1
                 If(Test-Path $Report1) {Write-Verbose "$Report1 already exists! The existing file is unchanged"}
                 Else {
                        Write-Host "Creating " -NoNewline;  Write-Host "$Report1" -F Yellow
                        $Group | Out-File $Report1
                    Foreach($G in $Group)
                            Remove-ADGroupMember -Identity $G -Members $I -Server $DC -Confirm:$false -ErrorAction Stop
                               # Traps terminating errors and writes the group names to $Report2
                             Trap [Microsoft.ActiveDirectory.Management.ADException] 
                               {Write-Verbose "Insufficient rights over ""$G"", saving to list..."
                                #$G | Export-Csv -Path $Report2 -NoTypeInformation -Append; continue
                                $G | Out-File $Report2 -Append; continue
                             Trap [Microsoft.ActiveDirectory.Management.ADIdentityNotFoundException] 
                               {Write-Verbose "Cannot find a group with identity: ""$G"", saving to list..."
                                #$G | Export-Csv $Report2 -NoTypeInformation -Append; continue
                                $G | Out-File $Report2 -Append; continue
                If(Test-Path $Report2) 
                  Write-Warning "GROUP MEMBERSHIPS REMAIN!!!"
                  Write-Verbose "Assign Remedy tickets for remaining groups based on the generated report"
                  #Start-Sleep -Seconds 2
                  #Start-Process  notepad -ArgumentList "$Report2"
                $Check = $User.Memberof | Get-ADGroup -Server $DC| Select-Object -ExpandProperty  samaccountname | Sort-Object
                If(!$Remove -and $Check -eq $null) 
                {Write-Warning "$($user.name) doesn't belong to any groups"} 
                Else {}
    • This reply was modified 1 year, 9 months ago by  L-Bo.
    • This reply was modified 1 year, 9 months ago by  L-Bo.

You must be logged in to reply to this topic.