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

Tagged: 

This topic contains 2 replies, has 3 voices, and was last updated by Profile photo of L-Bo L-Bo 6 months ago.

  • Author
    Posts
  • #38460
    Profile photo of Kivi
    Kivi
    Participant

    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

    Thanks,
    Kivi

  • #40672
    Profile photo of Geoff Duke
    Geoff Duke
    Participant

    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
    Profile photo of L-Bo
    L-Bo
    Participant

    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{
    < #
    .SYNOPSIS
      Retrieves group membership for target user object
    
    .DESCRIPTION
      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 
    
    .INPUTS
      None
    
    .OUTPUTS
      $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
     
    .NOTES
      Version:        2.2
      Author:         Logan "L-Bo" Boydell
      Creation Date:  03/03/2016
      Purpose/Change:
    
      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)
    
    .EXAMPLE
      PS C:\Windows\system32> Get-ADUMemberOf -Identity Billy.User
      DL-TestRestrictGroup
      DL-TestRestrictGroup1
    
      Outputs group memberships for AD User "Billy.User" to the console
    .EXAMPLE
      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
    #>
    
        [CmdletBinding()]
        [OutputType([int])]
        Param
        (
            # Param1 SamAccountName of AD User Object
            [Parameter(Mandatory=$true,
                       HelpMessage="Enter SamAccountName of User Object",
                       Position=0)]
            [string]$Identity,[switch]$Remove)
    
        Begin
        {
    
         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
    
        }
    
        Process
        {
         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($Remove)
             { 
                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
                               }
                        }
                }
             }
        }
        
        End
        {
            If($Remove)
             {
                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 {}
               }
            Else{$Group}
              
        }
    }
    
    • This reply was modified 6 months ago by Profile photo of L-Bo L-Bo.
    • This reply was modified 6 months ago by Profile photo of L-Bo L-Bo.

You must be logged in to reply to this topic.