Functions/Send-Email.ps1

<#
.SYNOPSIS
    This function sends an email containing optional attachments.
.DESCRIPTION
    This function sends an email containing optional attachments.
    It returns if the email was sent successfully.
#>

function Send-Email {
    [CmdletBinding(PositionalBinding=$false)]
    [OutputType([Bool])]
    param (
        # The credentials which will be used to send the email.
        [Parameter(Mandatory=$true)]
        [ValidateNotNull()]
        [PSCredential]$emailCredentials,

        # The email smtp server.
        [Parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [String]$smtpServer,

        # The port number on the email smtp server.
        [Parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [Int32]$portNumber,

        # The destination email address which the email will be sent.
        [Parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [ValidateScript({ Test-EmailAddressValidity $_ })]
        [String]$destinationEmailAddress,

        # The subject of the email.
        [Parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [String]$emailSubject,

        # The body of the email.
        [Parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [String]$emailBody,

        # An array containing the paths of multiple files to attach to the email.
        [Parameter(Mandatory=$true, ParameterSetName="multipleFiles")]
        [ValidateNotNull()]
        [ValidateScript({ $_.length -gt 1 -and !($_ | ForEach-Object { !(Test-Path $_ -ErrorAction SilentlyContinue) }) })]
        [PSObject[]]$attachmentFilePaths,

        # The path of a single file to attach to the email.
        [Parameter(Mandatory=$false, ParameterSetName="singleFile")]
        [ValidateNotNullOrEmpty()]
        [ValidateScript({ Test-Path $_ -ErrorAction SilentlyContinue })]
        [String]$attachmentFilePath
    )

    # Compress the attachments into a single .zip file
    if ($attachmentFilePaths) {
        try {
            $attachmentFilePaths = ConvertTo-Array $attachmentFilePaths
            $filePath = "$($env:TEMP)\$(New-Guid).zip"
            Compress-Archive -Path $attachmentFilePaths -DestinationPath $filePath -CompressionLevel Optimal
            $attachmentFile = Get-Item $filePath
        }
        catch {
            Write-Error "Error while compressing attachments into a single .zip file.`r`n$($_.Exception.Message)"
            return $false
        }

        if (!$attachmentFile) {
            Write-Error "Failed to compress attachments into a single .zip file.`r`n$($_.Exception.Message)"
            return $false
        }
        $attachmentFilePath = $attachmentFile.FullName
        Write-Information "Archive '$($attachmentFile.FullName)' containing the files specified will be attached to the email."
    }
    elseif ($attachmentFilePath) {
        Write-Information "'$($attachmentFilePath)' will be attached to the email."
    }

    # Create hash table for params
    $sendMailMessageParams = @{
        From        = $emailCredentials.Username
        Credential  = $emailCredentials
        SmtpServer  = $smtpServer
        Port        = $portNumber
        To          = $destinationEmailAddress
        Subject     = $emailSubject
        Body        = $emailBody
    }
    if (![String]::IsNullOrWhiteSpace($attachmentFilePath)) {
        $sendMailMessageParams.Add("Attachments", $attachmentFilePath)
    }

    # Send the email
    try {
        Write-Information "Sending the email to '$($destinationEmailAddress)'."
        Send-MailMessage @sendMailMessageParams -UseSsl
    }
    catch {
        Write-Error "Error while sending the email to '$($destinationEmailAddress)'.`r`n$($_.Exception.Message)"
        return $false
    }

    # Successfully sent the email
    return $true
}