Public/Get-LineManagerReport.ps1

<#
.SYNOPSIS
Generates a report of users and their respective line managers based on email input from a CSV file.
 
.DESCRIPTION
This function reads a CSV file containing user email addresses and departments. For each user, it attempts to find the line manager
email by querying across multiple Active Directory domains. The result is saved as a new CSV file, and any errors or missing data
(such as a user without a manager) are logged separately.
 
.PARAMETER InputCsvFile
Path to the input CSV file that contains user data.
 
.PARAMETER EmailColumn
The name of the column in the CSV file that contains user email addresses.
 
.PARAMETER DepartmentColumn
The name of the column in the CSV file that contains department names.
 
.PARAMETER Domains
An array of domain names to search for user and manager information (e.g., @("lab.company.com", "test.company.com")).
 
.OUTPUTS
A CSV file with columns: Username, Department, and ManagerEmail. Also writes errors to a timestamped log file.
 
.EXAMPLE
Get-LineManagerReport -InputCsvFile ".\employees.csv" -EmailColumn "Email" -DepartmentColumn "Department" -Domains @("corp.local", "test.corp.local")
 
.NOTES
The original input file will be deleted after processing.
#>


function Get-LineManagerReport {
    param (
        [Parameter(Mandatory = $true)]
        [string]$InputCsvFile,

        [Parameter(Mandatory = $true)]
        [string]$EmailColumn,

        [Parameter(Mandatory = $true)]
        [string]$DepartmentColumn,

        [Parameter(Mandatory = $true)]
        [string[]]$Domains
    )

    $timestamp = Get-Date -Format 'yyyyMMdd'
    $logDir    = Split-Path $InputCsvFile -Parent
    $logFile   = Join-Path $logDir ("LineManagerReport_Errors_$timestamp.log")
    $now       = Get-Date -Format 'dd/MM/yy HH:mm:ss'
    
    try {
        $users = Import-Csv -Path $InputCsvFile
        if (-not $users) {
            Add-Content -Path $logFile -Value "[${now}] WARNING: No data found in file: $InputCsvFile"
            return "Failed"
        }

        $outputList = New-Object System.Collections.Generic.List[object]

        foreach ($user in $users) {
            $email = $user.$EmailColumn
            $department = $user.$DepartmentColumn

            if ([string]::IsNullOrWhiteSpace($email) -or [string]::IsNullOrWhiteSpace($department)) {
                continue
            }

            $managerInfo = Get-ManagerInfoFromEmailAcrossDomains -UserEmail $email -Domains $Domains
            $managerEmail = $managerInfo.ManagerEmail

            if ([string]::IsNullOrWhiteSpace($managerEmail)) {
                Add-Content -Path $logFile -Value ("[{0}] ERROR: Manager not found for user [{1}]" -f (Get-Date -Format 'dd/MM/yy HH:mm:ss'), $email)
                continue
            }

            $outputList.Add([pscustomobject]@{
                Username     = $email
                Department   = $department
                ManagerEmail = $managerEmail
            })
        }

        $outputPath = Join-Path -Path $logDir -ChildPath ("{0}_{1}.csv" -f [IO.Path]::GetFileNameWithoutExtension($InputCsvFile), $timestamp)
        $outputList | Export-Csv -Path $outputPath -NoTypeInformation -Encoding UTF8

        # Delete original file after writing
        Remove-Item -Path $InputCsvFile -Force

        return "Success: Output saved to $outputPath"
    }
    catch {
        Add-Content -Path $logFile -Value ("[{0}] FATAL ERROR: {1}" -f (Get-Date -Format 'dd/MM/yy HH:mm:ss'), $_.Exception.Message)
        return "Failed"
    }
}