Copy AD group memberships from a source user to other users

Note: This blogpost is also posted on the peppercrew website.

This post is going to be short, but effective. One of those mondaine tasks you get to do as an IT administrator is assigning users to security groups for access to resources in the domain. Usually, when you ask the person making this request which security groups the user account needs membership for, they’ll tell you to use some other user account as a reference. Sometime you’ll even get a list of users that need to have the same memberships.

Rather than manually adding these users to the security groups you can use our buddy PowerShell to automate this process. I’ve spotted a few scripts out there that got some nice results, but I decided to take the best one and give it some extra sparkle. I can’t find the original script anymore so I can’t reference to it (sorry).

The main difference between my function and the ones already out there is that my version let’s you copy the memberships without removing the ones already present. If you do want an exact replica you can add the parameter -RemoveExisting to the command line. Also, my version allows you to copy memberships to multiple users. The function supports common parameters, such as Verbose, WhatIf and Confirm.

And now, without further ado: the function!

Downloadable version: here

<#
.Synopsis
   Function to copy group memberships from a source user to target users.
.DESCRIPTION
   Function to copy group memberships from a source user to multiple target users. It's
   also possible to make an exact duplicate by removing the existing memberships
   from the target accounts.
   Requires ActiveDirectory module.
.EXAMPLE
   Copy-GroupMembership -Source s.user -Targets t.user1,t.user2
   Adds the group memberships of user s.user to target users t.user1 and t.user2.
.EXAMPLE
   Copy-GroupMembership -Source s.user -Targets t.user1,t.user2 -RemoveExisting
   Adds the group memberships of user s.user to target users t.user1 and t.user2 and
   removes the existing group memberships from those target accounts, resulting in an
   exact duplicate.
.NOTES
   Author: Michaja van der Zouwen
.LINK
   https://itmicah.wordpress.com/2014/11/27/copy-ad-group-memberships-from-a-source-user-to-other-users</pre>
#>
function Copy-GroupMembership
{
    [CmdletBinding(SupportsShouldProcess=$true)]
    Param
    (
        # Source user account name
        [Parameter(Mandatory=$true,
                    Position=0)]
        [string]
        $Source,

        # Comma seperated list of target user accounts
        [Parameter(Mandatory=$true,
                    Position=1)]
        [string[]]
        $Targets,

        # Remove existing group memberships from target accounts
        [switch]
        $RemoveExisting
    )

    Write-Verbose "Retrieving source group memberships."
    $SourceUser = Get-ADUser $Source -Properties memberOf -ea 1

    foreach ($Target in $Targets) {

        Write-Verbose "Get group memberships for '$Target'."
        $TargetUser = Get-ADUser $Target -Properties memberOf

        If (!$TargetUser) {
            Write-Warning "Unable to find useraccount '$Target'. Skipping!"
        }
        else {
            # Hash table of source user groups.
            $List = @{}

            #Enumerate direct group memberships of source user.
            ForEach ($SourceDN In $SourceUser.memberOf)
            {
                # Add this group to hash table.
                $List.Add($SourceDN, $True)
                # Bind to group object.
                $SourceGroup = [ADSI]"LDAP://$SourceDN"

                Write-Verbose "Checking if '$target' is already a member of '$sourceDN'."
                If ($SourceGroup.IsMember("LDAP://" + $TargetUser.distinguishedName) -eq $False)
                {
                    if ($pscmdlet.ShouldProcess($Target, "Add to group '$SourceDN'"))
                    {
                        Write-Verbose "Adding '$target' to this group."
                        Add-ADGroupMember -Identity $SourceDN -Members $Target
                    }
                }
                else
                {
                    Write-Verbose "'$Target' is already a member of this group."
                }
            }

            #If required remove existing memberships
            If ($RemoveExisting)
            {
                Write-Verbose "Entering removal phase."

                # Enumerate direct group memberships of target user.
                ForEach ($TargetDN In $TargetUser.memberOf)
                {
                    Write-Verbose "Checking if '$Target' is a member of '$TargetDN'."
                    If ($List.ContainsKey($TargetDN) -eq $False)
                    {
                        if ($pscmdlet.ShouldProcess($Target, "Remove from group '$TargetDN'"))
                        {
                            # Source user not a member of this group.
                            Write-Verbose "Removing '$Target' from this group."
                            Remove-ADGroupMember $TargetDN $Target
                        }
                    }
                    else
                    {
                        Write-Verbose "'$Target' is not a member of this group."
                    }
                } # end foreach
            } # end If
        } # end If-else
    }  # end foreach Target
} # end function

Hopefully this will be helpfull to someone. If so, drop me a line in the comments.

Until next time!

MicaH

Advertisements

About MicaH

I'm a Technical Specialist at PepperByte BV (the Netherlands).
This entry was posted in Powershell and tagged , , , . Bookmark the permalink.

2 Responses to Copy AD group memberships from a source user to other users

  1. Wei-Yen Tan says:

    Hi micah,

    Thanks for your resources. This works great on one user, but when using the syntax like

    ./Copy-GroupMembership -Source weiyentan -Targets whitew,sampsonn

    I am getting the below error. What am i doing wrong?

    H:\Powershell\scripts\Copy-Groupmembership.ps1 : Cannot process argument transformation on parameter ‘Targets’. Cannot
    convert value to type System.String.
    At line:1 char:51
    + ./Copy-GroupMembership -Source weiyentan -Targets whitew,sampsonn
    + ~~~~~~~~~~~~~~~
    + CategoryInfo : InvalidData: (:) [Copy-Groupmembership.ps1], ParameterBindingArgumentTransformationExcep
    tion
    + FullyQualifiedErrorId : ParameterArgumentTransformationError,Copy-Groupmembership.ps1

    • MicaH says:

      Hi Wey-Yen. You’re not doing anything wrong, but I did. I’d set the type of the Targets input parameter to [string] instead of [string[]]. The last one is an array of strings which is what happens if you use a comma seperated list. I’ve updated the script so if you re-download it everything should work now. Thank you for pointing out the bug.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s