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
    }
}