Netflex Blog

Copy Active Directory user group membership

powershell

Sometimes when a new user is added to a team he or she needs all, or a selection of the Active Directory groups his colleagues are member of. Unfortunately, this can’t be done with the native Active Directory tools. To overcome this, I made a Powershell script to (selectively) copy Active Directory user group membership from one user to another.

What the script does

The script will ask you for a source and destination user to copy group membership information to.

Let’s copy the groups Donald Duck (dduck) is member of to Katrien (Daisy) Duck (Kduck).

 

Next you will be presented an overview of the group membership from the source user and to which groups the destination user will be added.

 

If you copy [A]ll groups from the source to the destination user, the script exits with the message “Group information copied from <source user> to <destination user>”.

 

If you want to copy some of the groups (not all) to the destination user press [S]elect.

 

A GUI will popup where you are able to multi select the groups to copy.

After pressing “OK” a summary of the added groups will be displayed.

 

Script

<#
15-02-2016 Michiel Elderson
Script copies Group membership from user A to user B
v1.0 - Michiel Elderson: Initial version
v1.1 - Michiel Elderson: Removed "CN=" notation from groupname in select box.
#>

param(
[parameter(Position=0,Mandatory=$true,ValueFromPipeline=$false,HelpMessage='User to retrieve Group Membership from')][string]$SourceAdUser,
[parameter(Position=1,Mandatory=$true,ValueFromPipeline=$false,HelpMessage='User to retrieve Group Membership from')][string]$DestinationAdUser

)

#melde:import module AD
import-module activedirectory

Write-host "
"

#Melde: Set some variables
$SourceAdUser = $SourceAdUser.ToUpper()
$DestinationAdUser = $DestinationAdUser.ToUpper()
$SourceGroups = (GET-ADUSER –Identity $SourceAdUser –Properties MemberOf | Select-Object MemberOf).MemberOf
$DestinationGroups  = (GET-ADUSER –Identity $DestinationAdUser –Properties MemberOf | Select-Object MemberOf).MemberOf

#Melde: Checks if accounts have group membership, if no group membership is found for either account script will exit
if ($SourceGroups -eq $null) {write-host "Source user not found" -foregroundcolor red;return}
if ($DestinationGroups -eq $null) {write-host "Destination user not found" -foregroundcolor red;return}

#Melde: Checks for differences, if no differences are found script will exit
if (-not (compare-object $DestinationGroups $SourceGroups | where-object {$_.sideindicator -eq '=>'})) {write-host "No difference between $SourceAdUser & $DestinationAdUser groupmembership found.
$DestinationAdUser will not be added to any additional groups." -foregroundcolor yellow;return}

#Melde:List current group membership source user
Foreach ($Sourcegroup in $SourceGroups){
Write-host "$SourceAdUser is member of    :"  (Get-AdGroup $SourceGroup).name
}

Write-host "
"

#Melde: List groups destination user will be added to
compare-object $DestinationGroups $SourceGroups | where-object {$_.sideindicator -eq '=>'} |
select -expand inputobject | foreach {write-host "$DestinationAdUser will be added to:"([regex]::split($_,'^CN=|,CN=Users|,CN=Builtin|,OU=|,DC=.+$'))[1]}

#Melde: Copy group membership
$title = "Copy GroupMembership to $DestinationAdUser ?"

$All = New-Object System.Management.Automation.Host.ChoiceDescription "&All", `
"Copy Groups."

$no = New-Object System.Management.Automation.Host.ChoiceDescription "&No", `
"Do not copy groups."

$select = New-Object System.Management.Automation.Host.ChoiceDescription "&Select", `
"Select groups to copy."

$options = [System.Management.Automation.Host.ChoiceDescription[]]($All, $no, $select)
$result = $host.ui.PromptForChoice($title, $message,$options, 0)

switch ($result)
{
0 {compare-object $DestinationGroups $SourceGroups | where-object {$_.sideindicator -eq '=>'} |
select -expand inputobject | foreach {add-adgroupmember "$_" $DestinationAdUser}
write-host "Group information copied from $SourceAduser to $DestinationAdUser" -foregroundcolor green

}
1 {write-host "No groups copied" -foregroundcolor red

}
2 {$selectedGroups = @(compare-object $DestinationGroups $SourceGroups | where-object {$_.sideindicator -eq '=>'} |
select -expand inputobject)

$global:Groups = @()

[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")

$objForm = New-Object System.Windows.Forms.Form
$objForm.Text = "Select groups"
$objForm.Size = New-Object System.Drawing.Size(450,500)
$objForm.StartPosition = "CenterScreen"

$objForm.KeyPreview = $True

$objForm.Add_KeyDown({if ($_.KeyCode -eq "Enter")
{
foreach ($objItem in $objListbox.SelectedItems)
{$global:Groups += $objItem}
$objForm.Close()
}
})

$objForm.Add_KeyDown({if ($_.KeyCode -eq "Escape")
{$objForm.Close()}})

$OKButton = New-Object System.Windows.Forms.Button
$OKButton.Location = New-Object System.Drawing.Size(10,420)
$OKButton.Size = New-Object System.Drawing.Size(75,23)
$OKButton.Text = "OK"

$OKButton.Add_Click(
{
foreach ($objItem in $objListbox.SelectedItems)
{$global:Groups += $objItem}
$objForm.Close()
})

$objForm.Controls.Add($OKButton)

$CancelButton = New-Object System.Windows.Forms.Button
$CancelButton.Location = New-Object System.Drawing.Size(85,420)
$CancelButton.Size = New-Object System.Drawing.Size(75,23)
$CancelButton.Text = "Cancel"
$CancelButton.Add_Click({$objForm.Close()})
$objForm.Controls.Add($CancelButton)

$objLabel = New-Object System.Windows.Forms.Label
$objLabel.Location = New-Object System.Drawing.Size(10,20)
$objLabel.Size = New-Object System.Drawing.Size(280,20)
$objLabel.Text = "Please select groups to copy:"
$objForm.Controls.Add($objLabel)

$objLabelversion = New-Object System.Windows.Forms.Label
$objLabelversion.Location = New-Object System.Drawing.Size(10,455)
$objLabelversion.Size = New-Object System.Drawing.Size(75,20)
$objLabelversion.Text = "v1.1"
$objForm.Controls.Add($objLabelversion)

$objListbox = New-Object System.Windows.Forms.Listbox
$objListbox.Location = New-Object System.Drawing.Size(10,40)
$objListbox.Size = New-Object System.Drawing.Size(410,20)
$objListBox.Sorted = $True

$objListbox.SelectionMode = "MultiExtended"

foreach ($selectedGroup in $selectedGroups){
[void] $objListBox.Items.Add(((("$selectedGroup").ToUpper())-replace "CN=","").split(',')[0])

}

$objListbox.Height = 375
$objForm.Controls.Add($objListbox)
$objForm.Topmost = $True

$objForm.Add_Shown({$objForm.Activate()})
[void] $objForm.ShowDialog()

foreach ($group in $global:groups){
add-adgroupmember "$group" $DestinationAdUser
write-host "$group added to $DestinationAdUser" -foregroundcolor green
}

}

}

Write-host "
"

 

Usage:

Save the script to Conf-UserGroupMembership.ps1. Run the script on a server where the “Active Directory module for Windows Powershell” is installed. Happy copying 🙂

Scroll to Top