Office 365 Copy/Replace Distribution Groups from Source to Destination User

by John C. Wray III Thursday, August 25, 2016 9:17 AM

We use Office 365 with DirSync. I was getting these requests a lot. The requests usually boiled down to please make sure this user is in all of the same groups as this other user.

You need to run this script as an admin. You also need to change the username and password for office 365. It will make sure it was launched as an administrator. Next it will ask for a source user, then destination user. Once it finds those, it will ask if you want to replace or add. Replace first removes all groups from the destination user. It then goes through the source user's groups and adds the destination user if it can.

 

Import-Module ActiveDirectory
# Get the ID and security principal of the current user account
$myWindowsID=[System.Security.Principal.WindowsIdentity]::GetCurrent()
$myWindowsPrincipal=new-object System.Security.Principal.WindowsPrincipal($myWindowsID)

# Get the security principal for the Administrator role
$adminRole=[System.Security.Principal.WindowsBuiltInRole]::Administrator

# Check to see if we are currently running "as Administrator"
if ($myWindowsPrincipal.IsInRole($adminRole))
{
# We are running "as Administrator" - so change the title and background color to indicate this
$Host.UI.RawUI.WindowTitle = $myInvocation.MyCommand.Definition + "(Elevated)"
$Host.UI.RawUI.BackgroundColor = "DarkBlue"
clear-host
}
else
{
# We are not running "as Administrator" - so relaunch as administrator

# Create a new process object that starts PowerShell
$newProcess = new-object System.Diagnostics.ProcessStartInfo "PowerShell";

# Specify the current script path and name as a parameter
$newProcess.Arguments = $myInvocation.MyCommand.Definition;

# Indicate that the process should be elevated
$newProcess.Verb = "runas";

# Start the new process
[System.Diagnostics.Process]::Start($newProcess);

# Exit from the current, unelevated, process
exit
}

#Get Current Buffer Size and Window Size
$bufferSize = $Host.UI.RawUI.BufferSize
$WindowSize = $host.UI.RawUI.WindowSize

$NewWindowWidth = 120
$NewWindowHeight = 70

#Buffer size cannot be smaller than Window size
If ($bufferSize.Width -lt $NewWindowWidth)
{
$bufferSize.Width = $NewWindowWidth
}
if ($bufferSize.Height -lt $NewWindowHeight)
{
$bufferSize.Height = $NewWindowHeight
}
$WindowSize.Width = $NewWindowWidth
$WindowSize.Height = $NewWindowHeight

$host.UI.RawUI.BufferSize = $buffersize
$host.UI.RawUI.WindowSize = $WindowSize



cls

#Find the UPN for the source user
write-host "================================================================================"
$tempFirstName = Read-Host "Enter the first name of the source user"
$tempFirstName += "*"
$tempLastName = Read-Host "Enter the last name of the source user"
$tempLastName += "*"
Try {
$tempUsers = Get-ADUser -filter {(GivenName -like $tempFirstName) -and (Surname -like $tempLastName)} -properties *
}
Catch {
write-host "Error in user query!" -foregroundcolor "red"
write-host "Tried to query using Get-ADUSer -filter {(GivenName -like " $tempFirstName " -and (Surname -like " $tempLastName ")} -properties *" -foregroundcolor "red" -backgroundcolor "white"
$error.clear()
Write-Host "Press any key to continue ..."
$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
exit
}
$tempAnswer = ""
foreach ($tempUser in $tempUsers)
{
$tempUserUPN = $tempUser.UserPrincipalName
$tempUserdisplayName = $tempUser.displayName
if (!$tempAnswer)
{
$tempAnswer = read-host "Is $tempUserdisplayName with a UPN of $tempUserUPN the correct source user? (y/n)"
if ($tempAnswer.ToUpper() -eq "Y")
{
$sourceUPN = $tempUserUPN
}
Else
{
$tempAnswer = ""
}
}
}
if (!$sourceUPN)
{
write-host "Never found a source user, exiting the script!"
Write-Host "Press any key to continue ..."
$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
exit
}
write-host "================================================================================"
write-host
write-host
write-host "================================================================================"

#Find the UPN for the destination user
$tempFirstName = Read-Host "Enter the first name of the destination user"
$tempFirstName += "*"
$tempLastName = Read-Host "Enter the last name of the destination user"
$tempLastName += "*"
Try {
$tempUsers = Get-ADUser -filter {(GivenName -like $tempFirstName) -and (Surname -like $tempLastName)} -properties *
}
Catch {
write-host "Error in user query!" -foregroundcolor "red"
write-host "Tried to query using Get-ADUSer -filter {(GivenName -like " $tempFirstName " -and (Surname -like " $tempLastName ")} -properties *" -foregroundcolor "red" -backgroundcolor "white"
$error.clear()
Write-Host "Press any key to continue ..."
$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
exit
}
$tempAnswer = ""
foreach ($tempUser in $tempUsers)
{
$tempUserUPN = $tempUser.UserPrincipalName
$tempUserdisplayName = $tempUser.displayName
if (!$tempAnswer)
{
$tempAnswer = read-host "Is $tempUserdisplayName with a UPN of $tempUserUPN the correct destination user? (y/n)"
if ($tempAnswer.ToUpper() -eq "Y")
{
$destUPN = $tempUserUPN
}
Else
{
$tempAnswer = ""
}
}
}
if (!$destUPN)
{
write-host "Never found a destination user, exiting the script!"
Write-Host "Press any key to continue ..."
$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
exit
}
write-host "================================================================================"

#Start the actual copy/replace now we have source and destination users.


$tempCopyReplace = read-host "Enter defaults to copy/adding groups. Enter (r) to replace groups"

#Connect to Azure/Office 365 if the password expires you would change it here
Import-Module MSOnline
$SecPass = ConvertTo-SecureString "Password123" -AsPlainText -Force
$O365Cred = New-Object System.Management.Automation.PSCredential ("AdminUser@YourDomain.com", $SecPass)
$O365Session = New-PSSession –ConfigurationName Microsoft.Exchange -ConnectionUri https://ps.outlook.com/powershell -Credential $O365Cred -Authentication Basic -AllowRedirection
Import-PSSession $O365Session
Connect-MsolService –Credential $O365Cred

if ($tempCopyReplace.toUpper() -eq "R")
{
#Remove all existing groups from destination user
$mailbox=get-Mailbox -identity $destUPN
$DN=$mailbox.DistinguishedName
$Filter = "Members -like ""$DN"""
Get-DistributionGroup -ResultSize Unlimited -Filter $Filter | Remove-DistributionGroupMember -Member $destUPN -Confirm:$false
}

write-host
write-host
write-host "================================================================="
write-host "Green = Added, Red = already a member or not added by the script."
write-host "================================================================="
write-host

#Load Source array with groups from the source user.
$mailbox=get-Mailbox -identity $sourceUPN
$DN=$mailbox.DistinguishedName
$Filter = "Members -like ""$DN"""
$tempSourceGroups = Get-DistributionGroup -ResultSize Unlimited -Filter $Filter

foreach($tempSourceGroup in $tempSourceGroups){
$tempGroupName = $tempSourceGroup.Identity

try {
Add-DistributionGroupMember $tempGroupName -member $destUPN -confirm:$false -ErrorAction stop
write-host $tempGroupName -foregroundcolor "green"
}
catch {
$tempReason = "Already a member"
if ($error -match "on-premises") {$tempReason = "On-Prem Group cannot add"}
write-host "$tempGroupName ($tempReason)"-foregroundcolor "red"
$error.clear()
}
}
write-host "================================================================================"
write-host "Finished adding to groups."


try {Remove-PSSession $O365Session}
catch {}

Write-Host "Press any key to continue ..."

$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")

 

Tags:

Microsoft | Exchange | Powershell

Comments are closed