# encoding: ascii
# api: powershell
# title: Copy-GroupMembership.ps1
# description: This script will copy the group membership from an existing user account to a new user account. This script relies on functions that I source in, so you’ll need to grab my code from http://scripts.patton-tech.com/browser/powershell/production/includes/ActiveDirectoryManagement.ps1
# version: 0.1
# type: script
# author: Jeff Patton
# license: CC0
# x-poshcode-id: 2964
# x-archived: 2013-05-20T04:47:11
# x-published: 2013-09-23T08:47:00
#
#
<#
.SYNOPSIS
Copy group membership between two accounts.
.DESCRIPTION
This script will copy the group membership from an existing user
account to a new user account.
.PARAMETER ADSPath
This is the LDAP URL to where your user accounts are stored
.PARAMETER NewUser
The username of the new user account
.PARAMETER SearchFilter
The searchFilter to pass on to AD, I'm using FSPs so it defaults
to foreignSecurityPrincipal, but it could be Person if you're
working with user accounts all within the same ActiveDirectory domain.
.PARAMETER ExistingUser
The username of the existing user account
.PARAMETER Verbose
Enable the debugging statements
.EXAMPLE
.\New-StudentWorker.ps1 -NewUser 'Newton' -ExistingUser 'Oldson' -ADSPath 'CN=ForeignSecurityPrincipals,DC=company,DC=com'
GroupDN UserDN Added
------- ------ -----
LDAP://CN=IGroup,OU=Profile,OU... LDAP://CN=S-1-5-21-57989841-1... The object already exists. (E...
LDAP://CN=ECSStaffProfessional... LDAP://CN=S-1-5-21-57989841-1... True
Description
-----------
This sample shows the syntax and working against FSPs, as well as a potential error you might encounter.
.EXAMPLE
.\New-StudentWorker.ps1 -NewUser 'Guest' -ExistingUser 'krbtgt' -ADSPath 'DC=company,DC=com' -SearchFilter '(objectCategory=Person)'
GroupDN UserDN Added
------- ------ -----
LDAP://CN=Denied RODC Password... LDAP://CN=Guest,CN=Users,DC=c... True
Description
-----------
This example shows the syntax for copying group membership between accounts in the same domain.
.NOTES
ScriptName : Copy-GroupMembership
Created By : jspatton
Date Coded : 09/22/2011 10:17:53
ScriptName is used to register events for this script
LogName is used to determine which classic log to write to
ErrorCodes
100 = Success
101 = Error
102 = Warning
104 = Information
.LINK
#>
Param
(
[Parameter(Mandatory=$true)]$ADSPath,
[Parameter(Mandatory=$true)]$NewUser,
$SearchFilter = '(objectCategory=foreignSecurityPrincipal)',
$ExistingUser
)
Begin
{
$ScriptName = $MyInvocation.MyCommand.ToString()
$LogName = "Application"
$ScriptPath = $MyInvocation.MyCommand.Path
$Username = $env:USERDOMAIN + "\" + $env:USERNAME
New-EventLog -Source $ScriptName -LogName $LogName -ErrorAction SilentlyContinue
$Message = "Script: " + $ScriptPath + "`nScript User: " + $Username + "`nStarted: " + (Get-Date).toString()
Write-EventLog -LogName $LogName -Source $ScriptName -EventID "104" -EntryType "Information" -Message $Message
if ($Verbose)
{
$DebugPreference = "Continue"
$VerbosePreference = $DebugPreference
}
# Dotsource in the functions you need.
. .\includes\ActiveDirectoryManagement.ps1
}
Process
{
if ($SearchFilter -like "*foreignSecurityPrincipal*")
{
Write-Verbose "Need to get a list of FSP objects and convert them to sAMAccountNames"
$Users = Get-ADObjects -ADSPath $ADSPath -SearchFilter $SearchFilter |foreach {$_.Properties.name |Convert-FspToUsername}
$NewUser = $Users |Where-Object {$_.sAMAccountName -like "*$($NewUser)"}
$ExistingUser = $Users |Where-Object {$_.sAMAccountName -like "*$($ExistingUser)"}
Write-Verbose "Found $($NewUser.sAMAccountName)"
Write-Verbose "Found $($ExistingUser.sAMAccountName)"
Write-Verbose "Get the group membership for CN=$($ExistingUser.Sid),$($ADSPath)"
$UserGroups = Get-UserGroupMembership -UserDN "CN=$($ExistingUser.Sid),$($ADSPath)"
foreach ($UserGroup in $UserGroups)
{
Write-Verbose "Try adding $($NewUser.sAMAccountName) to $UserGroup.GroupDN"
Add-UserToGroup -GroupDN $UserGroup.GroupDN -UserDN "LDAP://CN=$($NewUser.Sid),$($ADSPath)"
}
}
else
{
Write-Verbose "Get a list of user objects"
$Users = Get-ADObjects -ADSPath $ADSPath -SearchFilter $SearchFilter
$NewUser = $Users |Where-Object {$_.Properties.name -like "*$($NewUser)"}
$ExistingUser = $Users |Where-Object {$_.Properties.name -like "*$($ExistingUser)"}
Write-Verbose "Found $($NewUser.Properties.name)"
Write-Verbose "Found $($ExistingUser.Properties.name)"
Write-Verbose "Get the group membership for $($ExistingUser.Path)"
$UserGroups = Get-UserGroupMembership -UserDN $ExistingUser.Path
foreach ($UserGroup in $UserGroups)
{
Write-Verbose "Try adding $($NewUser.Properties.name) to $UserGroup.GroupDN"
Add-UserToGroup -GroupDN $UserGroup.GroupDN -UserDN $NewUser.Path
}
}
}
End
{
$Message = "Script: " + $ScriptPath + "`nScript User: " + $Username + "`nFinished: " + (Get-Date).toString()
Write-EventLog -LogName $LogName -Source $ScriptName -EventID "104" -EntryType "Information" -Message $Message
if ($Verbose)
{
$DebugPreference = "SilentlyContinue"
$VerbosePreference = $DebugPreference
}
}