Public/Remove-UsersFromDistributionLists.ps1
<#
.SYNOPSIS Removes specified users from one or more distribution groups based on an input CSV file. .DESCRIPTION This function processes a CSV file where each row contains a user email and one or more distribution group names (comma-separated). It verifies the user's membership in each group and removes them only if they are currently members. Logs are written to indicate success or errors, and output is also saved as a summary CSV. .PARAMETER InputFile Path to the CSV file containing user email and group columns. .PARAMETER GroupColumn The column name in the CSV that contains distribution group names (can be comma-separated). .PARAMETER EmailColumn The column name in the CSV that contains the user's email address. .PARAMETER LogPrefix Prefix for the output log and CSV files. .PARAMETER LogLocation Directory path where logs and reports will be saved (defaults to user profile path). .PARAMETER Domains An array of Active Directory domain names to search across (e.g., @("lab.company.com", "test.company.com")). .OUTPUTS Success or failure message. Writes logs and generates a summary CSV. .EXAMPLE Remove-UsersFromDistributionLists -InputFile "users.csv" -GroupColumn "Groups" -EmailColumn "Email" -LogPrefix "RemoveLog" -Domains @("corp.local") #> function Remove-UsersFromDistributionLists { 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 "RemoveUsers_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 not 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 Remove-UserFromGroup_ADSI -UserDN $userDN -GroupDN $groupObj Add-Content -Path $logPath -Value "$timestamp : [$email] successfully removed from [$group]" } catch { $timestamp = Get-Date -Format '[dd/MM/yy HH:mm:ss]' Add-Content -Path $errorLog -Value "$timestamp : ERROR Removing [$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 } } |