Public/Add-UsersToDistributionLists.ps1
<#
.SYNOPSIS Adds users to one or more distribution lists (DLs) based on an input CSV file. .DESCRIPTION This function reads an input CSV file where each row contains user email addresses and distribution list names. It checks if the user is already a member of the group. If not, it adds the user to the group using ADSI. The function logs all actions and errors to separate log files. .PARAMETER InputFile Path to the input CSV file containing the email addresses and group names. .PARAMETER GroupColumn The name of the column in the CSV that contains the group (DL) names (can be comma-separated). .PARAMETER EmailColumn The name of the column in the CSV that contains user email addresses. .PARAMETER LogPrefix Prefix to be used in the output log filenames. .PARAMETER LogLocation Optional. Directory where logs will be saved. Defaults to the current user profile folder. .PARAMETER Domains An array of domains to search within for resolving user and group information. .EXAMPLE Add-UsersToDistributionLists -InputFile "C:\input.csv" -GroupColumn "DLGroups" -EmailColumn "Email" -LogPrefix "DL_Add" -Domains @("test.corp.com", "lab.corp.com") .NOTES - The input CSV should contain at least two columns: one for email addresses and one for group names. - Group names in the group column can be comma-separated. - Membership check is done before attempting to add to avoid duplicates. #> function Add-UsersToDistributionLists { param ( [Parameter(Mandatory = $true)] [string]$InputFile, [Parameter(Mandatory = $true)] [string]$GroupColumn, [Parameter(Mandatory = $true)] [string]$EmailColumn, [Parameter(Mandatory = $true)] [string]$LogPrefix, [Parameter(Mandatory = $false)] [string]$LogLocation = $env:USERPROFILE, [Parameter(Mandatory = $true)] [string[]]$Domains ) begin { $label = Get-Date -Format "yyyyMMdd" $logPath = Join-Path $LogLocation "$LogPrefix`_$label.log" $csvLogPath = Join-Path $LogLocation "$LogPrefix.csv" $errorLog = Join-Path $LogLocation "AddUsers_Error_$label.log" $results = @() "[{0}] : Script Started`n" -f (Get-Date -Format 'dd/MM/yy HH:mm:ss') | Out-File -FilePath $logPath -Encoding UTF8 } process { try { $csv = Import-Csv -Path $InputFile foreach ($entry in $csv) { $email = $entry.$EmailColumn $groups = ($entry.$GroupColumn -split ',') | ForEach-Object { $_.Trim() } | Where-Object { $_ } foreach ($group in $groups) { $results += [pscustomobject]@{ EmailAddress = $email DLName = $group } $timestamp = Get-Date -Format '[dd/MM/yy HH:mm:ss]' # Check if user is already in group $membershipCheck = Check-UserGroupMembershipByEmail -Email $email -GroupCN $group -Domains $Domains if ($membershipCheck) { Add-Content -Path $logPath -Value "$timestamp : [$email] is already a member of [$group]" } else { try { # Get User DN $userDN = Get-ADUserByMail -Email $email -Domains $Domains if (-not $userDN) { "$timestamp : ERROR - User not found → $email`n" | Out-File -FilePath $errorLog -Append continue } # Get Group DN $groupObj = Get-ADGroupByCN -GroupCN $group -Domains $Domains if (-not $groupObj) { "$timestamp : ERROR - Group not found → $group`n" | Out-File -FilePath $errorLog -Append continue } $groupDN = $groupObj.distinguishedName # Add User to Group via ADSI $userDN = Get-ADUserByMail -Email $email -Domains $domains Add-UserToGroup_ADSI -UserDN $userDN -GroupDN $groupObj Add-Content -Path $logPath -Value "$timestamp : [$email] successfully added to [$group]" } catch { $timestamp = Get-Date -Format '[dd/MM/yy HH:mm:ss]' Add-Content -Path $errorLog -Value "$timestamp : ERROR adding [$email] to [$group] → $($_.Exception.Message)" } } } } $results | Export-Csv -Path $csvLogPath -NoTypeInformation -Encoding UTF8 Add-Content -Path $logPath -Value ("[{0}] : Script Completed`n" -f (Get-Date -Format 'dd/MM/yy HH:mm:ss')) return "Success" } catch { $timestamp = Get-Date -Format '[dd/MM/yy HH:mm:ss]' "$timestamp : ERROR processing file → $($_.Exception.Message)`n" | Out-File -FilePath $errorLog -Append return "Failed" } } end { Remove-Variable -Name results, csv, entry, email, groups -ErrorAction SilentlyContinue } } |