mirror of
https://github.com/admindroid-community/powershell-scripts.git
synced 2025-12-17 08:25:20 +00:00
Copy Members From One DL to Another
This commit is contained in:
parent
4a646ed5aa
commit
c777e13869
@ -0,0 +1,211 @@
|
||||
<#
|
||||
=============================================================================================
|
||||
Name: Copy Members from One Distribution List to Another
|
||||
Version: 1.0
|
||||
Website: o365reports.com
|
||||
|
||||
|
||||
Script Highlights:
|
||||
~~~~~~~~~~~~~~~~~
|
||||
1. Fetches members and owners from the source DL and adds them to the target DL.
|
||||
2. Helps to copy DL members from one to another. (if not present already).
|
||||
3. Can copy managers from one DL to another. (if not present already).
|
||||
4. The script automatically verifies and installs the Exchange Online PowerShell module (if not installed) upon your confirmation.
|
||||
5. Exports an output log file in TXT format that shows the result of the operation.
|
||||
6. The script can be executed with MFA enabled account too.
|
||||
7. The script supports certificate-based authentication (CBA) too.
|
||||
8. The script is schedular-friendly.
|
||||
|
||||
For detailed Script execution: https://o365reports.com/2025/04/08/copy-members-from-one-distribution-list-to-another/
|
||||
|
||||
|
||||
============================================================================================
|
||||
#>
|
||||
Param
|
||||
(
|
||||
[Parameter(Mandatory = $False)]
|
||||
[string]$SourceGroup=$Null,
|
||||
[string]$TargetGroup=$Null,
|
||||
[Switch]$CopyOwnersOnly,
|
||||
[Switch]$CopyMembersOnly,
|
||||
[string]$UserName=$Null,
|
||||
[string]$Password=$Null,
|
||||
[string]$Organization,
|
||||
[string]$ClientId,
|
||||
[string]$CertificateThumbPrint
|
||||
)
|
||||
|
||||
#Connection module
|
||||
Function Connect_Module {
|
||||
#Check for Exchange Online module installation
|
||||
$ExchangeModule = Get-Module ExchangeOnlineManagement -ListAvailable
|
||||
if($ExchangeModule.count -eq 0) {
|
||||
Write-Host ExchangeOnline module is not available -ForegroundColor Yellow
|
||||
$confirm = Read-Host Do you want to Install ExchangeOnline module? [Y] Yes [N] No
|
||||
if($confirm -match "[Yy]") {
|
||||
Write-Host "Installing ExchangeOnline module ..."
|
||||
Install-Module ExchangeOnlineManagement -Repository PSGallery -AllowClobber -Force -Scope CurrentUser
|
||||
Import-Module ExchangeOnlineManagement
|
||||
}
|
||||
else {
|
||||
Write-Host "ExchangeOnline Module is required. To Install ExchangeOnline module use 'Install-Module ExchangeOnlineManagement' cmdlet."
|
||||
Exit
|
||||
}
|
||||
}
|
||||
|
||||
#Connect Exchange Online
|
||||
Write-Host "`nConnecting Exchange Online module ..."
|
||||
if(($UserName -ne "") -and ($Password -ne "")) {
|
||||
$SecuredPassword = ConvertTo-SecureString -AsPlainText $Password -Force
|
||||
$Credential = New-Object System.Management.Automation.PSCredential $UserName,$SecuredPassword
|
||||
Connect-ExchangeOnline -Credential $Credential
|
||||
}
|
||||
elseif($Organization -ne "" -and $ClientId -ne "" -and $CertificateThumbprint -ne "") {
|
||||
Connect-ExchangeOnline -AppId $ClientId -CertificateThumbprint $CertificateThumbprint -Organization $Organization -ShowBanner:$false
|
||||
}
|
||||
else {
|
||||
Connect-ExchangeOnline -ShowBanner:$false
|
||||
}
|
||||
}
|
||||
|
||||
#Output log function
|
||||
Function Log-Data {
|
||||
param ([string]$UserName,$UserType,$Status,$Message = "")
|
||||
$Result = if ($Status -eq "Failed") {
|
||||
"- Failed to copy $UserName as a $UserType to the target group. Error: $Message"
|
||||
} elseif(($Status -eq "Already a Member") -or ($Status -eq"Already a Owner")){
|
||||
"- Skipped adding $UserName as $UserType. The user is already a $UserType in the target group."
|
||||
} else {
|
||||
"- $UserName has been successfully copied as $UserType to the target group."
|
||||
}
|
||||
Add-Content -Path $OutputLog -Value $Result
|
||||
}
|
||||
|
||||
$Script:CopiedMembersCount = 0
|
||||
$Script:CopiedOwnersCount = 0
|
||||
$Script:ExistingMembersCount = 0
|
||||
$Script:ExistingOwnersCount = 0
|
||||
|
||||
#Funtion to copy members only to another distribution group
|
||||
Function Copy_Members
|
||||
{
|
||||
$ProcessedUserCount=0
|
||||
|
||||
$SourceGroupMemberNames = Get-DistributionGroupMember -Identity $SourceGroup
|
||||
$TargetGroupMemberNames = Get-DistributionGroupMember -Identity $TargetGroup
|
||||
|
||||
ForEach($SourceGroupMemberName in $SourceGroupMemberNames)
|
||||
{
|
||||
$SourceMemberName = $SourceGroupMemberName.DisplayName
|
||||
Write-Progress -Activity "Copying Members From $SourceGroup to $TargetGroup " -Status "Processed member Count : $ProcessedUserCount" -CurrentOperation " Currently Processing Member $($SourceMemberName)"
|
||||
Try
|
||||
{
|
||||
if($SourceGroupMemberName.Guid -in $TargetGroupMemberNames.Guid){
|
||||
Log-Data -UserName $SourceGroupMemberName.DisplayName -UserType "member" -Status "Already a Member"
|
||||
$Script:ExistingMembersCount++
|
||||
}
|
||||
else{
|
||||
Add-DistributiongroupMember -Identity $TargetGroup -Member $($SourceGroupMemberName.DistinguishedName) -ErrorAction Stop
|
||||
Log-Data -UserName $SourceGroupMemberName.DisplayName -UserType "member" -Status "Successfully Copied"
|
||||
$Script:CopiedMembersCount++
|
||||
}
|
||||
}
|
||||
Catch
|
||||
{
|
||||
Log-Data -UserName $Member.DisplayName -UserType "member" -Status "Failed" -Message $_.Exception.Message
|
||||
}
|
||||
$ProcessedUserCount++
|
||||
}
|
||||
}
|
||||
|
||||
#Funtion to copy owners only to another distribution group
|
||||
Function Copy_Owners
|
||||
{
|
||||
$ProcessedUserCount=0
|
||||
|
||||
$SourceGroupOwnerNames = Get-DistributionGroup -Identity $SourceGroup | Select -ExpandProperty ManagedBy
|
||||
$TargetGroupOwnerNames = Get-DistributionGroup -Identity $TargetGroup | Select -ExpandProperty ManagedBy
|
||||
|
||||
ForEach($SourceGroupOwnerName in $SourceGroupOwnerNames)
|
||||
{
|
||||
$Owner = Get-Recipient -Identity $SourceGroupOwnerName
|
||||
Write-Progress -Activity "Copying owner From $SourceGroup To $TargetGroup " -Status "Processed owner Count: $ProcessedUserCount" -CurrentOperation "Currently Processing Owner $($Owner.Displayname)"
|
||||
try{
|
||||
if($SourceGroupOwnerName -in $TargetGroupOwnerNames)
|
||||
{
|
||||
Log-Data -UserName $Owner.DisplayName -UserType "owner" -Status "Already a Owner"
|
||||
$Script:ExistingOwnersCount++
|
||||
}
|
||||
else
|
||||
{
|
||||
Set-DistributionGroup -Identity $TargetGroup -ManagedBy @{Add="$($Owner.PrimarySmtpAddress)"} -ErrorAction Stop
|
||||
Log-Data -UserName $Owner.DisplayName -UserType "owner" -Status "Successfully Copied"
|
||||
$Script:CopiedOwnersCount++
|
||||
}
|
||||
}
|
||||
catch{
|
||||
Log-Data -UserName $Owner.DisplayName -UserType "owner" -Status "Failed" -Message $_.Exception.Message
|
||||
}
|
||||
$ProcessedUserCount++
|
||||
}
|
||||
}
|
||||
|
||||
#Function to return output log file
|
||||
Function OpenOutputLog
|
||||
{
|
||||
Write-Host "`nSummary of Distribution List Membership Changes" -ForegroundColor DarkYellow
|
||||
Write-Host "`n$($ExistingMembersCount) member(s) and $($ExistingOwnersCount) owner(s) from source DL is already present in target DL."
|
||||
#Write-Host "`n$($ExistingMembersCount) members and $($ExistingOwnersCount) owners already present in both distribution lists."
|
||||
Write-Host "`nThe script successfully copied $($CopiedMembersCount) members and $($CopiedOwnersCount) owners to the target DL."
|
||||
|
||||
#Open Output file after execution
|
||||
If((Test-Path -Path $OutputLog) -eq "True")
|
||||
{
|
||||
Write-Host `nThe log file available in :`n -NoNewline -ForegroundColor Yellow
|
||||
Write-Host $OutputLog
|
||||
Write-Host `n~~ Script prepared by AdminDroid Community ~~`n -ForegroundColor Green
|
||||
Write-Host "~~ Check out " -NoNewline -ForegroundColor Green; Write-Host "admindroid.com" -ForegroundColor Yellow -NoNewline; Write-Host " to get access to 1800+ Microsoft 365 reports. ~~" -ForegroundColor Green `n`n
|
||||
$Prompt = New-Object -ComObject wscript.shell
|
||||
$UserInput = $Prompt.popup("Do you want to open log file?",` 0,"Open log File",4)
|
||||
If($UserInput -eq 6)
|
||||
{
|
||||
Invoke-Item "$OutputLog"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#Execution starts here
|
||||
Connect_Module
|
||||
If($SourceGroup -eq "" -or ($TargetGroup -eq ""))
|
||||
{
|
||||
If($SourceGroup -eq "")
|
||||
{
|
||||
$SourceGroup = Read-Host "`nEnter the source DL mail Id"
|
||||
}
|
||||
If($TargetGroup -eq "")
|
||||
{
|
||||
$TargetGroup = Read-Host "`nEnter the target DL mail Id"
|
||||
}
|
||||
}
|
||||
|
||||
$Location = Get-Location
|
||||
$OutputLog="$Location\Copy_DL_Membership_Log_$((Get-Date -format yyyy-MMM-dd-ddd` hh-mm` tt).ToString()).txt"
|
||||
If($CopyOwnersOnly.IsPresent)
|
||||
{
|
||||
Copy_Owners
|
||||
}
|
||||
ElseIf($CopyMemberOnly.IsPresent)
|
||||
{
|
||||
Copy_Members
|
||||
}
|
||||
Else
|
||||
{
|
||||
Copy_Owners
|
||||
Copy_Members
|
||||
}
|
||||
|
||||
#Open output log file
|
||||
OpenOutputLog
|
||||
|
||||
#Disconnect Exchange Online session
|
||||
Disconnect-ExchangeOnline -Confirm:$false | Out-Null
|
||||
Loading…
x
Reference in New Issue
Block a user