Emailimo.psm1

function Email {
    [CmdLetBinding(SupportsShouldProcess = $True)]
    param([Parameter(Mandatory = $false, Position = 0)][ScriptBlock] $Email,
        [string[]] $To,
        [string[]] $CC,
        [string[]] $BCC,
        [string] $ReplyTo,
        [string] $From,
        [string] $Subject,
        [alias('SelfAttach')][switch] $AttachSelf,
        [string] $AttachSelfName,
        [string] $Server,
        [string] $Username,
        [int] $Port = 587,
        [string] $Password,
        [switch] $PasswordFromFile,
        [switch] $PasswordAsSecure,
        [switch] $SSL,
        [ValidateSet('Low', 'Normal', 'High')] [string] $Priority = 'Normal',
        [ValidateSet('None', 'OnSuccess', 'OnFailure', 'Delay', 'Never')] $DeliveryNotifications = 'None',
        [string] $Encoding = 'Unicode',
        [string] $FilePath,
        [bool] $Supress = $true)
    $StartTime = Start-TimeLog
    $ServerParameters = [ordered] @{From = $From
        To = $To
        CC = $CC
        BCC = $BCC
        ReplyTo = $ReplyTo
        Server = $Server
        Login = $Username
        Password = $Password
        PasswordAsSecure = $PasswordAsSecure
        PasswordFromFile = $PasswordFromFile
        Port = $Port
        EnableSSL = $SSL
        Encoding = $Encoding
        Subject = $Subject
        Priority = $Priority
        DeliveryNotifications = $DeliveryNotifications
    }
    $Attachments = [System.Collections.Generic.List[string]]::new()
    $Body = New-HTML -UseCssLinks -UseJavaScriptLinks {[Array] $EmailParameters = Invoke-Command -ScriptBlock $Email
        foreach ($Parameter in $EmailParameters) {
            switch ($Parameter.Type) {
                HeaderTo {$ServerParameters.To = $Parameter.Addresses}
                HeaderCC {$ServerParameters.CC = $Parameter.Addresses}
                HeaderBCC {$ServerParameters.BCC = $Parameter.Addresses}
                HeaderFrom {$ServerParameters.From = $Parameter.Address}
                HeaderReplyTo {$ServerParameters.ReplyTo = $Parameter.Address}
                HeaderSubject {$ServerParameters.Subject = $Parameter.Subject}
                HeaderServer {
                    $ServerParameters.Server = $Parameter.Server
                    $ServerParameters.Port = $Parameter.Port
                    $ServerParameters.Login = $Parameter.UserName
                    $ServerParameters.Password = $Parameter.Password
                    $ServerParameters.PasswordFromFile = $Parameter.PasswordFromFile
                    $ServerParameters.PasswordAsSecure = $Parameter.PasswordAsSecure
                    $ServerParameters.EnableSSL = $Parameter.SSL
                }
                HeaderAttachment {$Attachments.Add($Parameter.FilePath)}
                HeaderOptions {
                    $ServerParameters.DeliveryNotifications = $Parameter.DeliveryNotifications
                    $ServerParameters.Encoding = $Parameter.Encoding
                    $ServerParameters.Priority = $Parameter.Priority
                }
                Default {$Parameter}
            }
        }}
    if ($FilePath) {Save-HTML -FilePath $FilePath -HTML $Body}
    if ($AttachSelf) {
        if ($AttachSelfName) {$TempFilePath = "$(Get-TemporaryDirectory)\$($AttachSelfName).html"} else {$TempFilePath = ''}
        $Saved = Save-HTML -FilePath $TempFilePath -HTML $Body -Supress $false
        if ($Saved) {$Attachments.Add($Saved)}
    }
    $MailSentTo = "To: $($ServerParameters.To -join ', '); CC: $($ServerParameters.CC -join ', '); BCC: $($ServerParameters.BCC -join ', ')".Trim()
    if ($pscmdlet.ShouldProcess("$MailSentTo", "Email")) {
        $EmailOutput = Send-Email -EmailParameters $ServerParameters -Body ($Body -join '') -Attachment $Attachments
        if (-not $Supress) {$EmailOutput}
    }
    $EndTime = Stop-TimeLog -Time $StartTime -Option OneLiner
    Write-Verbose "Email - Time to send: $EndTime"
}
function EmailAttachment {
    [CmdletBinding()]
    param([string[]] $FilePath)
    [PSCustomObject] @{Type = 'HeaderAttachment'
        FilePath = $FilePath
    }
}
function EmailBCC {
    [CmdletBinding()]
    param([string[]] $Addresses)
    [PsCustomObject] @{Type = 'HeaderBCC'
        Addresses = $Addresses
    }
}
function EmailBody {
    [CmdletBinding()]
    param([Parameter(Mandatory = $false, Position = 0)][ScriptBlock] $EmailBody,
        [RGBColors] $Color,
        [RGBColors] $BackGroundColor,
        [alias('Size')][int] $FontSize,
        [ValidateSet('normal', 'bold', 'bolder', 'lighter', '100', '200', '300', '400', '500', '600', '700', '800', '900')][string] $FontWeight,
        [ValidateSet('normal', 'italic', 'oblique')][string] $FontStyle,
        [ValidateSet('normal', 'small-caps')][string] $FontVariant,
        [string] $FontFamily ,
        [ValidateSet('left', 'center', 'right', 'justify')][string] $Alignment,
        [ValidateSet('none', 'line-through', 'overline', 'underline')][string] $TextDecoration,
        [ValidateSet('uppercase', 'lowercase', 'capitalize')][string] $TextTransform,
        [ValidateSet('rtl')][string] $Direction)
    $newHTMLSplat = @{}
    if ($Alignment) {$newHTMLSplat.Alignment = $Alignment}
    if ($FontSize) {$newHTMLSplat.FontSize = $FontSize}
    if ($TextTransform) {$newHTMLSplat.TextTransform = $TextTransform}
    if ($Color) {$newHTMLSplat.Color = $Color}
    if ($FontFamily) {$newHTMLSplat.FontFamily = $FontFamily}
    if ($Direction) {$newHTMLSplat.Direction = $Direction}
    if ($FontStyle) {$newHTMLSplat.FontStyle = $FontStyle}
    if ($TextDecoration) {$newHTMLSplat.TextDecoration = $TextDecoration}
    if ($BackGroundColor) {$newHTMLSplat.BackGroundColor = $BackGroundColor}
    if ($FontVariant) {$newHTMLSplat.FontVariant = $FontVariant}
    if ($FontWeight) {$newHTMLSplat.FontWeight = $FontWeight}
    [bool] $SpanRequired = $false
    foreach ($Entry in $newHTMLSplat.GetEnumerator()) {
        if ((Get-ObjectCount -Object $Entry.Value) -gt 0) {
            $SpanRequired = $true
            break
        }
    }
    if ($SpanRequired) {New-HTMLSpanStyle @newHTMLSplat {Invoke-Command -ScriptBlock $EmailBody}} else {Invoke-Command -ScriptBlock $EmailBody}
}
function EmailCC {
    [CmdletBinding()]
    param([string[]] $Addresses)
    [PsCustomObject] @{Type = 'HeaderCC'
        Addresses = $Addresses
    }
}
function EmailFrom {
    [CmdletBinding()]
    param([string] $Address)
    [PsCustomObject] @{Type = 'HeaderFrom'
        Address = $Address
    }
}
function EmailHeader {
    [CmdletBinding()]
    param([Parameter(Mandatory = $false, Position = 0)][ScriptBlock] $EmailHeader)
    $EmailHeaders = Invoke-Command -ScriptBlock $EmailHeader
    $EmailHeaders
}
function EmailHTML {
    [CmdletBinding()]
    param([ScriptBlock] $HTML)
    Invoke-Command -ScriptBlock $HTML
}
function EmailList {
    [CmdletBinding()]
    param([ScriptBlock]$ListItems,
        [ValidateSet('Unordered', 'Ordered')] [string] $Type = 'Unordered',
        [RGBColors] $Color,
        [RGBColors] $BackGroundColor,
        [int] $FontSize,
        [ValidateSet('normal', 'bold', 'bolder', 'lighter', '100', '200', '300', '400', '500', '600', '700', '800', '900')][string] $FontWeight,
        [ValidateSet('normal', 'italic', 'oblique')][string] $FontStyle,
        [ValidateSet('normal', 'small-caps')][string] $FontVariant,
        [string] $FontFamily ,
        [ValidateSet('left', 'center', 'right', 'justify')][string] $Alignment,
        [ValidateSet('none', 'line-through', 'overline', 'underline')][string] $TextDecoration,
        [ValidateSet('uppercase', 'lowercase', 'capitalize')][string] $TextTransform,
        [ValidateSet('rtl')][string] $Direction,
        [switch] $LineBreak)
    $newHTMLSplat = @{}
    if ($Alignment) {$newHTMLSplat.Alignment = $Alignment}
    if ($FontSize) {$newHTMLSplat.FontSize = $FontSize}
    if ($TextTransform) {$newHTMLSplat.TextTransform = $TextTransform}
    if ($Color) {$newHTMLSplat.Color = $Color}
    if ($FontFamily) {$newHTMLSplat.FontFamily = $FontFamily}
    if ($Direction) {$newHTMLSplat.Direction = $Direction}
    if ($FontStyle) {$newHTMLSplat.FontStyle = $FontStyle}
    if ($TextDecoration) {$newHTMLSplat.TextDecoration = $TextDecoration}
    if ($BackGroundColor) {$newHTMLSplat.BackGroundColor = $BackGroundColor}
    if ($FontVariant) {$newHTMLSplat.FontVariant = $FontVariant}
    if ($FontWeight) {$newHTMLSplat.FontWeight = $FontWeight}
    if ($LineBreak) {$newHTMLSplat.LineBreak = $LineBreak}
    New-HTMLList @newHTMLSplat -Type $Type {Invoke-Command -ScriptBlock $ListItems}
}
function EmailListItem {
    [CmdletBinding()]
    param([string] $Text,
        [RGBColors[]] $Color = @(),
        [RGBColors[]] $BackGroundColor = @(),
        [int[]] $FontSize = @(),
        [ValidateSet('normal', 'bold', 'bolder', 'lighter', '100', '200', '300', '400', '500', '600', '700', '800', '900')][string[]] $FontWeight = @(),
        [ValidateSet('normal', 'italic', 'oblique')][string[]] $FontStyle = @(),
        [ValidateSet('normal', 'small-caps')][string[]] $FontVariant = @(),
        [string[]] $FontFamily = @(),
        [ValidateSet('left', 'center', 'right', 'justify')][string[]] $Alignment = @(),
        [ValidateSet('none', 'line-through', 'overline', 'underline')][string[]] $TextDecoration = @(),
        [ValidateSet('uppercase', 'lowercase', 'capitalize')][string[]] $TextTransform = @(),
        [ValidateSet('rtl')][string[]] $Direction = @(),
        [switch] $LineBreak)
    $newHTMLTextSplat = @{Alignment = $Alignment
        FontSize = $FontSize
        TextTransform = $TextTransform
        Text = $Text
        Color = $Color
        FontFamily = $FontFamily
        Direction = $Direction
        FontStyle = $FontStyle
        TextDecoration = $TextDecoration
        BackGroundColor = $BackGroundColor
        FontVariant = $FontVariant
        FontWeight = $FontWeight
        LineBreak = $LineBreak
    }
    New-HTMLListItem @newHTMLTextSplat
}
function EmailOptions {
    [CmdletBinding()]
    param([ValidateSet('Low', 'Normal', 'High')] [string] $Priority = 'Normal',
        [ValidateSet('None', 'OnSuccess', 'OnFailure', 'Delay', 'Never')] $DeliveryNotifications = 'None',
        [string] $Encoding = 'Unicode')
    [PsCustomObject] @{Type = 'HeaderOptions'
        Encoding = $Encoding
        DeliveryNotifications = $DeliveryNotifications
        Priority = $Priority
    }
}
function EmailReplyTo {
    [CmdletBinding()]
    param([string] $Address)
    [PsCustomObject] @{Type = 'HeaderReplyTo'
        Address = $Address
    }
}
function EmailServer {
    [CmdletBinding()]
    param([string] $Server,
        [int] $Port = 587,
        [string] $UserName,
        [string] $Password,
        [switch] $PasswordAsSecure,
        [switch] $PasswordFromFile,
        [switch] $SSL)
    [PsCustomObject] @{Type = 'HeaderServer'
        Server = $Server
        Port = $Port
        UserName = $UserName
        Password = $Password
        PasswordAsSecure = $PasswordAsSecure
        PasswordFromFile = $PasswordFromFile
        SSL = $SSL
    }
}
function EmailSubject {
    [CmdletBinding()]
    param([string] $Subject)
    [PsCustomObject] @{Type = 'HeaderSubject'
        Subject = $Subject
    }
}
function EmailTable {
    [CmdletBinding()]
    param([Parameter(Mandatory = $false, Position = 0)][ScriptBlock] $ConditionalFormatting,
        [alias('Table')][Array] $DataTable,
        [string[]][ValidateSet('copyHtml5', 'excelHtml5', 'csvHtml5', 'pdfHtml5')] $Buttons = @('copyHtml5', 'excelHtml5', 'csvHtml5', 'pdfHtml5'),
        [string[]][ValidateSet('numbers', 'simple', 'simple_numbers', 'full', 'full_numbers', 'first_last_numbers')] $PagingStyle = 'full_numbers',
        [int[]]$PagingOptions = @(15, 25, 50, 100),
        [switch]$DisablePaging,
        [switch]$DisableOrdering,
        [switch]$DisableInfo,
        [switch]$HideFooter,
        [switch]$DisableColumnReorder,
        [switch]$DisableProcessing,
        [switch]$DisableResponsiveTable,
        [switch]$DisableSelect,
        [switch]$DisableStateSave,
        [switch]$DisableSearch,
        [switch]$ScrollCollapse,
        [switch]$OrderMulti,
        [switch]$Filtering,
        [ValidateSet('Top', 'Bottom', 'Both')][string]$FilteringLocation = 'Bottom',
        [string[]][ValidateSet('display', 'cell-border', 'compact', 'hover', 'nowrap', 'order-column', 'row-border', 'stripe')] $Style = @('display', 'compact'),
        [string]$TextWhenNoData = 'No data available.',
        [int] $ScreenSizePercent = 0,
        [string[]] $DefaultSortColumn,
        [int[]] $DefaultSortIndex,
        [ValidateSet('Ascending', 'Descending')][string] $DefaultSortOrder = 'Ascending',
        [alias('Search')][string]$Find,
        [switch] $InvokeHTMLTags,
        [switch] $DisableNewLine)
    New-HTMLTable -DataTable $DataTable -HideFooter:$HideFooter -Buttons $Buttons -PagingStyle $PagingStyle -PagingOptions $PagingOptions -DisablePaging:$DisablePaging -DisableOrdering:$DisableOrdering -DisableInfo:$DisableInfo -DisableColumnReorder:$DisableColumnReorder -DisableProcessing:$DisableProcessing -DisableResponsiveTable:$DisableResponsiveTable -DisableSelect:$DisableSelect -DisableStateSave:$DisableStateSave -DisableSearch:$DisableSearch -ScrollCollapse:$ScrollCollapse -Style $Style -TextWhenNoData:$TextWhenNoData -ScreenSizePercent $ScreenSizePercent -ConditionalFormatting $ConditionalFormatting -DefaultSortColumn $DefaultSortColumn -DefaultSortIndex $DefaultSortIndex -DefaultSortOrder $DefaultSortOrder -Find $Find -OrderMulti:$OrderMulti -Filtering:$Filtering -FilteringLocation $FilteringLocation -InvokeHTMLTags:$InvokeHTMLTags -DisableNewLine:$DisableNewLine
}
function EmailText {
    [CmdletBinding()]
    param([Parameter(Mandatory = $false, Position = 0)][ScriptBlock] $TextBlock,
        [string[]] $Text,
        [RGBColors[]] $Color = @(),
        [RGBColors[]] $BackGroundColor = @(),
        [alias('Size')][int[]] $FontSize = @(),
        [ValidateSet('normal', 'bold', 'bolder', 'lighter', '100', '200', '300', '400', '500', '600', '700', '800', '900')][string[]] $FontWeight = @(),
        [ValidateSet('normal', 'italic', 'oblique')][string[]] $FontStyle = @(),
        [ValidateSet('none', 'line-through', 'overline', 'underline')][string[]] $TextDecoration = @(),
        [ValidateSet('normal', 'small-caps')][string[]] $FontVariant = @(),
        [string[]] $FontFamily = @(),
        [ValidateSet('left', 'center', 'right', 'justify')][string[]] $Alignment = @(),
        [ValidateSet('uppercase', 'lowercase', 'capitalize')][string[]] $TextTransform = @(),
        [ValidateSet('rtl')][string[]] $Direction = @(),
        [switch] $LineBreak,
        [switch] $SkipParagraph)
    if ($TextBlock) {$Text = (Invoke-Command -ScriptBlock $TextBlock)}
    $newHTMLTextSplat = @{Alignment = $Alignment
        FontSize = $FontSize
        TextTransform = $TextTransform
        Text = $Text
        Color = $Color
        FontFamily = $FontFamily
        Direction = $Direction
        FontStyle = $FontStyle
        TextDecoration = $TextDecoration
        BackGroundColor = $BackGroundColor
        FontVariant = $FontVariant
        FontWeight = $FontWeight
        LineBreak = $LineBreak
        SkipParagraph = $SkipParagraph
    }
    New-HTMLText @newHTMLTextSplat
}
function EmailTextBox {
    [CmdletBinding()]
    param([Parameter(Mandatory = $false, Position = 0)][ScriptBlock] $TextBlock,
        [RGBColors[]] $Color = @(),
        [RGBColors[]] $BackGroundColor = @(),
        [alias('Size')][int[]] $FontSize = @(),
        [ValidateSet('normal', 'bold', 'bolder', 'lighter', '100', '200', '300', '400', '500', '600', '700', '800', '900')][string[]] $FontWeight = @(),
        [ValidateSet('normal', 'italic', 'oblique')][string[]] $FontStyle = @(),
        [ValidateSet('none', 'line-through', 'overline', 'underline')][string[]] $TextDecoration = @(),
        [ValidateSet('normal', 'small-caps')][string[]] $FontVariant = @(),
        [string[]] $FontFamily = @(),
        [ValidateSet('left', 'center', 'right', 'justify')][string[]] $Alignment = @(),
        [ValidateSet('uppercase', 'lowercase', 'capitalize')][string[]] $TextTransform = @(),
        [ValidateSet('rtl')][string[]] $Direction = @(),
        [switch] $LineBreak)
    if ($TextBlock) {
        $Text = (Invoke-Command -ScriptBlock $TextBlock)
        if ($Text.Count) {$LineBreak = $true}
    }
    foreach ($T in $Text) {
        $newHTMLTextSplat = @{Alignment = $Alignment
            FontSize = $FontSize
            TextTransform = $TextTransform
            Text = $T
            Color = $Color
            FontFamily = $FontFamily
            Direction = $Direction
            FontStyle = $FontStyle
            TextDecoration = $TextDecoration
            BackGroundColor = $BackGroundColor
            FontVariant = $FontVariant
            FontWeight = $FontWeight
            LineBreak = $LineBreak
        }
        New-HTMLText @newHTMLTextSplat -SkipParagraph
    }
}
function EmailTo {
    [CmdletBinding()]
    param([string[]] $Addresses)
    [PsCustomObject] @{Type = 'HeaderTo'
        Addresses = $Addresses
    }
}
Export-ModuleMember -Function @('Email', 'EmailAttachment', 'EmailBCC', 'EmailBody', 'EmailCC', 'EmailFrom', 'EmailHeader', 'EmailHTML', 'EmailList', 'EmailListItem', 'EmailOptions', 'EmailReplyTo', 'EmailServer', 'EmailSubject', 'EmailTable', 'EmailText', 'EmailTextBox', 'EmailTo') -Alias @()