mirror of
https://github.com/admindroid-community/powershell-scripts.git
synced 2025-12-17 16:35:19 +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