Modules/ADEHM.Mail.psm1
|
#requires -Version 5.1 <# ADEHM.Mail.psm1 Sends the report by email (SMTP). Uses System.Net.Mail directly (rather than Send-MailMessage, obsolete since PowerShell 7.x) to remain compatible with PowerShell 5.1 / 7. #> function Send-ADEHMReport { <# .SYNOPSIS Emails the HTML report according to the Mail section of the configuration. .PARAMETER BodyHtml Optional email-optimized HTML body (from New-ADEHMEmailReport). Used when EmbedReportInBody is enabled; the raw report file is only a fallback (degraded rendering in Outlook). .PARAMETER Credential SMTP service account credentials. When omitted, the default Windows credentials of the execution context are used. #> [CmdletBinding()] param( [Parameter(Mandatory)] [hashtable]$Config, [Parameter(Mandatory)] [string]$ReportPath, [Parameter(Mandatory)] [datetime]$RunDate, [string]$BodyHtml, [System.Management.Automation.PSCredential]$Credential ) if (-not $Config.Mail.Enabled) { Write-ADEHMLog -Level INFO -Module Mail -Message 'Mail delivery disabled in configuration.' return $false } if (-not (Test-Path -LiteralPath $ReportPath)) { Write-ADEHMError -Server 'localhost' -Module 'Mail' -Exception "Report not found: $ReportPath" ` -ProbableCause 'HTML report generation failed before sending.' ` -Recommendation 'Review HTML module errors in the log.' return $false } # ABSOLUTE path required: the .NET Attachment constructor resolves # relative paths against the process working directory (often # C:\Windows\system32), not the current PowerShell location. $ReportPath = (Resolve-Path -LiteralPath $ReportPath).ProviderPath $attachment = $null $mail = $null $smtp = $null try { $smtp = New-Object System.Net.Mail.SmtpClient($Config.Mail.SmtpServer, $Config.Mail.Port) $smtp.EnableSsl = [bool]$Config.Mail.UseSsl if ($Credential) { $smtp.Credentials = $Credential.GetNetworkCredential() } else { $smtp.UseDefaultCredentials = $true } $mail = New-Object System.Net.Mail.MailMessage $mail.From = $Config.Mail.From foreach ($to in $Config.Mail.To) { $mail.To.Add($to) } foreach ($cc in $Config.Mail.Cc) { $mail.CC.Add($cc) } $mail.Subject = ($Config.Mail.Subject -f $RunDate.ToString('yyyy-MM-dd HH:mm')) $mail.IsBodyHtml = $true if ($Config.Mail.EmbedReportInBody) { if ($BodyHtml) { # Email-optimized rendering (tables + inline styles) from # New-ADEHMEmailReport: the only reliable option in Outlook # (Word rendering engine). $mail.Body = $BodyHtml } else { # Fallback: raw file (degraded rendering in Outlook) $mail.Body = Get-Content -LiteralPath $ReportPath -Raw -Encoding UTF8 } } else { $mail.Body = "The ADEHM report of $($RunDate.ToString('yyyy-MM-dd HH:mm')) is attached." } if ($Config.Mail.AttachReport) { $attachment = New-Object System.Net.Mail.Attachment($ReportPath) $mail.Attachments.Add($attachment) } $smtp.Send($mail) Write-ADEHMLog -Level INFO -Module Mail -Message "Report sent to $($Config.Mail.To -join ', ')" return $true } catch { $msg = $_.Exception.Message if ($msg -match 'path|find') { $cause = 'Client-side file path error (BEFORE any SMTP contact): the report was not found at the expected location.' $reco = 'Check the report path in the log; use absolute paths in the configuration.' } elseif ($msg -match 'authent|credential|5\.7') { $cause = 'The SMTP server rejected authentication or the sender address.' $reco = 'Check the SMTP account, the allowed From address, and the server relay restrictions.' } else { $cause = 'SMTP server unreachable, port blocked by a firewall, or incorrect SSL/port setting.' $reco = 'Check SmtpServer/Port/UseSsl in the configuration and run Test-NetConnection <smtp> -Port <port>.' } Write-ADEHMError -Server 'localhost' -Module 'Mail' -Exception $msg ` -ProbableCause $cause -Recommendation $reco return $false } finally { if ($attachment) { $attachment.Dispose() } if ($mail) { $mail.Dispose() } if ($smtp) { $smtp.Dispose() } } } Export-ModuleMember -Function Send-ADEHMReport |