Public/Send-ModernMailMessage.ps1


function Send-ModernMailMessage {
    <#
    .SYNOPSIS
        Sends an email message.
    .DESCRIPTION
        The Send-ModernMailMessage cmdlet sends an email message from within PowerShell.
    .EXAMPLE
        Send-ModernMailMessage -From "user01@fabrikam.com" -To "user02@fabrikam.com" -Subject "Test mail"
        Send-ModernMailMessage -From "user01@fabrikam.com" -To "user02@fabrikam.com" -Subject "Test mail" -SmtpServer smtp.contoso.com -UseSsl -Port 587
        Send-ModernMailMessage -From "user01@fabrikam.com" -To "user02@fabrikam.com" -Subject "Test mail" -ClientId [AppId] -CertificateThumbprint [Thumbprint] -TenantId [TenantId]
    .INPUTS
        None
    .OUTPUTS
        System.Reflection.Assembly
    .NOTES
        Use "Enable-MailMessageAlias" to enable the command "Send-MailMessage".
    #>


    # Sends email messages from PowerShell using either Microsoft Graph API or SMTP with OAuth 2.0 (Modern Auth). Supports advanced features such as attachments, HTML body, CC/BCC, and flexible authentication methods, making it a modern replacement for the legacy Send-MailMessage cmdlet.

    [CmdletBinding(DefaultParameterSetName = 'GRAPH')]
    [OutputType([System.Reflection.Assembly])]
    #[OutputType([System.Reflection.Assembly], [string])]
    param (
        # The path and file names of files to be attached to the email message.
        [Parameter(Position = 0)]
        [Alias("Attachments")]
        [String[]]$Attachment,

        # Email addresses that receive a copy of the mail but are not listed as recipients of the message.
        [Parameter(Position = 1)]
        #[Array] $Bcc,
        [String[]]$Bcc,

        # The body (content) of the email message.
        [Parameter(Position = 2)]
        #[string[]] $Text,
        [Alias("Message")]
        [String]$Body,

        # Indicates that the value of the Body parameter contains HTML.
        [Parameter(Position = 3)]
        #[Alias("Body")]
        #[string[]] $HTML,
        [Switch]$BodyAsHtml,

        # The encoding used for the body and subject.
        # Explicitly reference System.Text.Encoding
        [Parameter(Position = 4, ParameterSetName = 'SMTP')]
        [System.Text.Encoding]$Encoding = [System.Text.Encoding]::Default,

        # Email addresses to which a carbon copy (CC) of the email message is sent.
        [Parameter(Position = 5)]
        #[Array] $Cc,
        [String[]]$Cc,

        # Delivery notifications (if accepted by the recipient)
        [Parameter(Position = 6)]
        [Alias("Dno")]
        #[System.Net.Mail.DeliveryNotificationOptions]$DeliveryNotificationOption,
        # Explicitly reference System.Net.Mail
        [ValidateSet('None', 'OnSuccess', 'OnFailure', 'Delay', 'Never')]
        # Delivery notification options with validation
        [String[]]$DeliveryNotificationOption,

        # The address from which the mail is sent.
        [Parameter(Position = 7, ParameterSetName = 'GRAPH', Mandatory = $false)]
        [Parameter(Position = 7, ParameterSetName = 'SMTP', Mandatory = $false)]
        [Parameter(Position = 7, ParameterSetName = 'TEAMS', Mandatory = $true)]
        #[object] $From,
        [Alias("UserId")]
        [Alias("UserPrincipalName")]
        [ValidateNotNullOrEmpty()]
        [String]$From,

        # The name of the SMTP server that sends the email message (legacy).
        [Parameter(Position = 8, ParameterSetName = 'SMTP')]
        [Alias('Host')]
        [Alias('Server')]
        [String]$SmtpServer = "smtp.office365.com",

        # The priority of the email message.
        [Parameter(Position = 9)]
        #[System.Net.Mail.MailPriority]$Priority, # Explicitly reference System.Net.Mail.MailPriority
        [Alias('Importance')]
        [ValidateSet('Low', 'Normal', 'High')]
        [string]$Priority,

        # Specifies additional email addresses (other than the From address) to use to reply to this message
        [Parameter(Position = 10)]
        #[string] $ReplyTo,
        [String[]]$ReplyTo,

        # The subject of the email message.
        [Parameter(Position = 11)]
        #[string] $Subject,
        [String]$Subject,

        # The addresses to which the mail is sent
        [Parameter(Position = 12, Mandatory = $true)]
        #[Array] $To,
        #[Parameter(Mandatory = $true)]
        [ValidateNotNullOrEmpty()]
        [String[]]$To,

        # A user account that has permission to perform this action (legacy).
        [Parameter(Position = 13)]
        [System.Management.Automation.Credential()]
        [PSCredential]$Credential,

        # Use the Secure Sockets Layer (SSL) protocol to establish a connection (legacy).
        # Default: StartTls, On: Ssl, Off: N/A
        [Parameter(Position = 14, ParameterSetName = 'SMTP', Mandatory = $false)]
        [Switch]$UseSsl,

        # SecureSocketOptions (use with -UseSsl)
        [ValidateSet("None", "Auto", "SslOnConnect", "StartTls", "StartTlsWhenAvailable")]
        [Parameter(ParameterSetName = 'SMTP', Mandatory = $false)]
        [Alias("Encryption")]
        [Alias("SslEncryption")]
        [Alias("SecureSocketOption")]
        [string]$SslMethod,

        # An alternate port on the SMTP server.
        # Default: 587, Custom: 25, Ssl: 465
        [Parameter(Position = 15, ParameterSetName = 'SMTP', Mandatory = $false)]
        [Int32]$Port = 587,

        # Indicates whether to save the message in Sent Items.
        [Parameter(ParameterSetName = 'GRAPH')]
        [Switch]$SaveToSentItems,

        # Indicates whether a read receipt is requested for the message.
        #ToDevelop:IsReadReceiptRequested
        [Parameter(ParameterSetName = 'GRAPH')]
        [Switch]$RequestReadReceipt,

        # Indicates whether a delivery receipt is requested for the message.
        #ToDevelop: IsDeliveryReceiptRequested
        [Parameter(ParameterSetName = 'GRAPH')]
        [Switch]$RequestDeliveryReceipt,

        #ToDevelop: Message
        #ToDevelop: BodyParameter

        # Disable Telemetry
        # If set, telemetry information will not be logged.
        [Parameter(Mandatory = $false, HelpMessage = 'Disable telemetry')]
        [switch]$DisableTelemetry,

        # Modus defines the mode of operation for sending notifications.
        # Default: None
        # Fallback: Graph with Delegation (user-based interaction).
        # Fallback: User-based delegation for Microsoft Graph (interactive).
        # Recommended:
        # - 'GRAPH': App-only authentication (certificate-based) for Graph API.
        # - 'SMTP': SMTP-based email sending (e.g., OAuth2 authentication).
        # - 'TEAMS': Teams webhook notification (send notifications to a Teams channel).
        [Parameter(ParameterSetName = 'GRAPH', Mandatory = $false)]
        [Parameter(ParameterSetName = 'SMTP', Mandatory = $false)]
        [Parameter(ParameterSetName = 'TEAMS', Mandatory = $false)]
        [ValidateSet('GRAPH', 'SMTP', 'TEAMS')]
        [String]$Modus = 'GRAPH',

        #[String]$Auth = 'GRAPH',

        # Specifies the application ID of the service principal that is used in application-based authentication.
        [Parameter(ParameterSetName = 'GRAPH', Mandatory = $false)]
        [Parameter(ParameterSetName = 'TEAMS', Mandatory = $false)]
        [Alias('AppId')]
        [Alias('ApplicationId')]
        [string]$ClientId,

        # Specifies the ID of a tenant.
        [Parameter(ParameterSetName = 'GRAPH', Mandatory = $false)]
        [Parameter(ParameterSetName = 'TEAMS', Mandatory = $false)]
        # Organization
        [string]$TenantId,

        # Specifies the certificate thumbprint of a digital public key X.509 certificate of an application that has permission to perform this action.
        [Parameter(ParameterSetName = 'GRAPH', Mandatory = $false)]
        [Parameter(ParameterSetName = 'TEAMS', Mandatory = $false)]
        [Alias('Thumbprint')]
        [string]$CertificateThumbprint
    )

    <#
    Reference:
        https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/send-mailmessage?view=powershell-7.5
        https://ss64.com/ps/send-mailmessage.html
        https://learn.microsoft.com/en-us/powershell/module/microsoft.graph.users.actions/send-mgusermail?view=graph-powershell-1.0
 
        # With DisplayName
        Send-MailMessage -From "User01 <user01@fabrikam.com>"" -To "User02 <user02@fabrikam.com>" -Subject "Test mail"
        Send-MailMessage -To "User01 <user01@contoso.com>" -From "User02 <user02@contoso.com>" -Subject "Test mail" -SmtpServer smtp.contoso.com -UseSsl -Port 587
    #>


    ## Defensive handling for Encoding parameter
    #if ($null -eq $Encoding) {
    # $Encoding = [System.Text.Encoding]::Default
    #} elseif ($Encoding -is [string]) {
    # $Encoding = [System.Text.Encoding]::GetEncoding($Encoding)
    #}

    Write-Debug "Active ParameterSet: $($PSCmdlet.ParameterSetName)"
    if (-not $Modus) { $Modus = $PSCmdlet.ParameterSetName; Write-Warning "Override Modus: $($Modus)"}

    if (-not $From) { throw "Parameter 'From' is required." }
    if (-not $To)   { throw "Parameter 'To' is required." }

    # Compatibility values
    if ($SmtpServer) { Write-Verbose "Legacy: $($SmtpServer)" }
    if ($Credential) { Write-Verbose "Legacy: $($Credential)" }
    if ($UseSsl) { Write-Verbose "Legacy: $($UseSsl)" }
    if ($Port) { Write-Verbose "Legacy: $($Port)" }

    # Development values
    #if ($Attachments) { Write-Verbose "Development: $($Attachments)" }
    if ($Cc) { Write-Verbose "Development: $($Cc)" }
    if ($Bcc) { Write-Verbose "Development: $($Bcc)" }
    if ($DeliveryNotificationOption) { Write-Verbose "Development: $($DeliveryNotificationOption)" } # DNO
    if ($Priority) { Write-Verbose "Development: $($Priority)" }
    if ($ReplyTo) { Write-Verbose "Development: $($ReplyTo)" }
    if ($SaveToSentItems) { Write-Verbose "Development: $($SaveToSentItems)" }
    if ($RequestReadReceipt) { Write-Verbose "Development: $($RequestReadReceipt)" } # DNO
    if ($RequestDeliveryReceipt) { Write-Verbose "Development: $($RequestDeliveryReceipt)" } # DNO
    if ($Encoding) { Write-Verbose "Development: $($Encoding)" }


    if ($DisableTelemetry -or $Script:DisableTelemetry) {
        $Script:DisableTelemetry = $true
    } else {
        Write-Telemetry -EventName "SendModernMailMessage"
    }

    # -- Authentication
    switch ($Modus) {
        'GRAPH' {
            # Graph - Application
            # Implement Microsoft Graph API logic using certificate for authentication (app-based)
            Write-Debug "Sending email via Microsoft Graph Application (certificate-based) to $To"
            # Implement Microsoft Graph API logic using certificate-based authentication (app-only)
            Write-Debug "Sending email via Microsoft Graph Application (app-only authentication) to $To"

            if ($ClientId -and $TenantId -and $CertificateThumbprint) {
                Connect-MgGraph `
                    -ClientId $ClientId `
                    -TenantId $TenantId `
                    -CertificateThumbprint $CertificateThumbprint
            }

            try {
                $user = Get-MgUser -UserId $From -ErrorAction Stop
                Write-Debug "Search From: $($user.DisplayName)"
            } catch {
                Write-Warning "The user specified in -From ('$From') does not exist in Microsoft 365."

                # Fallback to User Auth. if available
                if ((Get-EntraContext).Account) {
                    $From = (Get-EntraContext).Account
                    Write-Warning "Override From: $($From)"
                }
            }
        }
        'SMTP' {
            # Implement SMTP with OAuth2 authentication here
            # Write-Debug "Sending email via SMTP to $To"
            # Implement SMTP with OAuth2 authentication here
            # Write-Debug "Sending email via SMTP to $To"

            # SMTP
            Import-Module EntraAuth

            ## During the Connectiong
            #$clientId = $application.AppId
            #$tenantId = $context.TenantId
            #$token = Connect-EntraService -ClientID $clientId -TenantID $tenantId -Service GraphBeta -PassThru
            #$token.Scopes

            ##Get-EntraService
            #$graphCfg = @{
            # Name = 'Graph' # Office 365 Exchange Online
            # ServiceUrl = 'https://graph.microsoft.com/v1.0'
            # Resource = 'https://graph.microsoft.com' # https://outlook.office365.com/
            # DefaultScopes = @()
            # HelpUrl = 'https://developer.microsoft.com/en-us/graph/quick-start'
            # Header = @{ }
            # NoRefresh = $false
            #}
            #Register-EntraService @graphCfg

            if (-not (Get-EntraContext)) {
                # Connect-EntraService -ClientID Graph -Scopes "SMTP.Send" -Service GraphBeta
                #Connect-EntraService -ClientID Graph -Scopes "SMTP.Send" -Service GraphBeta
                Connect-EntraService -ClientID Graph -Scopes "https://outlook.office365.com/SMTP.Send" -Service GraphBeta
                #Get-EntraService
            }
            $IsDelegated = $true
            $From = if ($IsDelegated) {(Get-EntraContext).Account} else {$From}


            # After already being connected
            $token = Get-EntraToken -Service GraphBeta
            #$token.Scopes # SMTP.Send

            #$token | fl *
            #$xauth2 = $token.AccessToken
            #$secure_xauth2 = ConvertTo-SecureString -AsPlainText $xauth2 -Force # Token
            #$secure_xauth2 = ConvertTo-SecureString -AsPlainText "[Password]" -Force # Pw (with Enabled MFA)
            ##[pscredential]$credential = New-Object System.Management.Automation.PSCredential("AutomateB@contoso.onmicrosoft.com", $secure_xauth2)

            # Get-CASMailbox user@domain.com | fl SmtpClientAuthenticationDisabled
            # Set-CASMailbox user@domain.com -SmtpClientAuthenticationDisabled $false

        }
        'TEAMS' {
            # Implement Teams webhook notification logic here
            Write-Debug "Sending Teams notification to $To"

            if ($ClientId -and $TenantId -and $CertificateThumbprint) {
                Connect-MicrosoftTeams`
                    -CertificateThumbprint $CertificateThumbprint `
                    -ApplicationId $ClientId `
                    -TenantId $TenantId
            }

        }
        default {
            # Handle invalid modus, if necessary
            Write-Debug "Invalid modus specified: $Modus"
            # You can also add additional handling for invalid modus, like logging or exit

            # Graph - Delegated (Fallback)
            # Implement Microsoft Graph API logic using delegated user consent (interactive)
            Write-Debug "Sending email via Microsoft Graph Delegation (user-based) to $To"
            # Implement Microsoft Graph API logic using delegated user consent (interactive)
            Write-Debug "Sending email via Microsoft Graph Delegation (user-based authentication) to $To"

            # Only connect if not already connected
            if (-not (Get-MgContext)) {
                Connect-MgGraph -Scopes "Mail.Send" -NoWelcome
            }
            $IsDelegated = $true
            $From = if ($IsDelegated) {(Get-MgContext).Account} else {$From}
            #$From = if ($Modus -eq 'GRAPH_DELEGATION') {(Get-MgContext).Account} else {$From}
        }
    }


    # -- Settings
    #$To = if ($To.Count -gt 1) {} else { $To[0] } # Handle Array

    $MessageBody = @{
        contentType = if ($BodyAsHtml) { "HTML" } else { "Text" }
        #content = if ($Body) { $Body -join [System.Environment]::NewLine } else { "" }
        content = if ($Body) { $Body -join [System.Environment]::NewLine } else { "This email is sent via Microsoft Graph." }
    }
    if (!$Subject) { $Subject  = "Test message from ModernMailTools (Modus: $Modus)" }


    if ($Attachment){
        try {
            #$Attachment = "..\_readme.md"
            #Test-Path $Attachment # True
            #(Get-Item -Path $Attachment).Length -lt 3000000 # 3191 | True
            if ((Test-Path $Attachment) -and ((Get-Item -Path $Attachment).Length -lt 3000000)) {
                # Attachments are under 4MB or empty

                #Get File Name and Base64 string
                $FileName = (Get-Item -Path $Attachment).Name
                $FileBytes = [Convert]::ToBase64String([IO.File]::ReadAllBytes($Attachment))
                Write-Verbose "Name: $($FileName)"
                Write-Verbose "Length: $($FileBytes.Length)"
            } else {
                <#Do this if attachments are over 4MB#>
            }
        }    catch {
            Write-Verbose $_
            #Write-Error $_.Exception.Message
        }
    }

    # -- Send
    if ($From) { Write-Verbose "Send-From: $($From)"}
    if ($To) { Write-Verbose "Send-To: $($To)"}
    if ($Subject) { Write-Verbose "Send-Subject: $($Subject)"}
    if ($MessageBody) { Write-Debug "Send-Body: $($MessageBody | Out-String)"}

    Write-Debug "Modus: $($Modus)"
    switch ($Modus) {
        'GRAPH' {
            # --- MS Graph

            $params = [ordered] @{
                # https://docs.microsoft.com/en-us/graph/api/resources/message?view=graph-rest-1.0
                message         = [ordered] @{
                    subject                    = $Subject
                    body                       = $MessageBody
                    #from = $From
                    toRecipients               = @(
                        @{
                            emailAddress = @{
                                address = $To[0]
                            }
                        }
                    )
                    #toRecipients = @(
                    # @{
                    # emailAddress = @{
                    # address = "meganb@contoso.com"
                    # }
                    # }
                    #)
                    #ccRecipients = @()
                    #bccRecipients = @()
                    #replyTo = @()
                    #importance = $Priority
                    #isReadReceiptRequested = $RequestReadReceipt.IsPresent
                    #isDeliveryReceiptRequested = $RequestDeliveryReceipt.IsPresent
                }
                #saveToSentItems = -not $DoNotSaveToSentItems.IsPresent
                #saveToSentItems = $false
                saveToSentItems = $SaveToSentItems.IsPresent
            }
            Write-Debug ($params.Values | Out-String)

            #Send-MgUserMail -UserId $From -Message $params
            try {
                Send-MgUserMail -UserId $From -BodyParameter $params
            } catch {
                throw "Failed to send mail: $($_.Exception.Message)"
            }

        }
        'SMTP' {
            # --- SMTP
            #Send-MKMailMessage -To "admin@contoso.onmicrosoft.com" -From "AutomateB@contoso.onmicrosoft.com" -Subject "Test" -SmtpServer "smtp.office365.com" -Credential $credential -Port 25
            # > Send-MKMailMessage: as8758.net SMTPBLOCKER ESMTP Service not available
            #Send-MKMailMessage -To "admin@contoso.onmicrosoft.com" -From "AutomateB@contoso.onmicrosoft.com" -Subject "Test" -SmtpServer "smtp.office365.com" -Credential $credential -Port 587
            # > Send-MKMailMessage: 535: 5.7.139 Authentication unsuccessful, the request did not meet the criteria to be authenticated successfully
            # > Send-MKMailMessage: 535: 5.7.139 Authentication unsuccessful, the request did not meet the criteria to be authenticated successfully.

            If (!(Get-Package MailKit)){
                #
                Find-Package -Name 'MailKit' -Source 'https://www.nuget.org/api/v2' | Install-Package #-Verbose
            }

            #Get-Package MailKit
            #(Get-Package -ProviderName NuGet -Name 'MailKit') | fl *
            $folderNameMail = Split-Path (Get-Package -ProviderName NuGet -Name 'MailKit').Source -Parent
            $folderNameMime = Split-Path (Get-Package -ProviderName NuGet -Name 'MimeKit').Source -Parent
            #C:\Program Files\PackageManagement\NuGet\Packages\MailKit.4.11.0\MailKit.4.11.0.nupkg
            # C:\Program Files\PackageManagement\NuGet\Packages\MailKit.4.11.0

            [System.Reflection.Assembly]::LoadFile("$($folderNameMail)\lib\net48\MailKit.dll") > $null
            [System.Reflection.Assembly]::LoadFile("$($folderNameMime)\lib\net48\MimeKit.dll") > $null
            Add-Type -Path "$($folderNameMail)\lib\net48\MailKit.dll"
            Add-Type -Path "$($folderNameMime)\lib\net48\MimeKit.dll"

            #$smtpClient = New-Object MailKit.Net.Smtp.SmtpClient
            #[MailKit.Net.Smtp.SmtpClient]
            $smtpClient = [MailKit.Net.Smtp.SmtpClient]::new()

            # Set TLS to automatically negotiate security
            switch ($UseSSL) {
                $true {
                    $SSLAuto = [MailKit.Security.SecureSocketOptions]::Auto
                    Write-Verbose "Parameter -UseSSL is enabled."
                }
                $false {
                    Write-Warning "Parameter -UseSSL is disabled."
                }
            }


            if ($UseSSL -and $SslMethod){
                $SSLAuto = [MailKit.Security.SecureSocketOptions]::$($SslMethod)
            #} elseif ($UseSSL -and $SslMethod -eq "SslOnConnect" -and $Port -ne "587") {
            #} elseif {$UseSSL -and $SslMethod -eq "None" {
            }

            # $SSLAuto = [MailKit.Security.SecureSocketOptions]::SslOnConnect
            # $SSLAuto = [MailKit.Security.SecureSocketOptions]::StartTlsWhenAvailable
            # $SSLAuto = [MailKit.Security.SecureSocketOptions]::Auto
            ## https://mimekit.net/docs/html/T_MailKit_Security_SecureSocketOptions.htm

            If(Resolve-DnsName $SmtpServer) {Write-Debug "DNS Works"}

            #$smtpClient.Connect('smtp.gmail.com', 587, $False)
            $smtpClient.Connect($SmtpServer, $Port, $SSLAuto)
                # No such host is known.

            #$smtpClient.Authenticate($Username, ( Convert-SecureToPlaintext -String $channel.Definition.password))
            #$smtpClient.Authenticate('myemail1@gmail.com', 'AppSpecificPassword' )
            #$smtpClient.Authenticate($Username, $Password)

            # $token.AccessToken = OAuth2 Token (replace this with your actual OAuth2 token)

            #$username = "test"
            #$username = $token.TokenData.unique_name
            $username = $token.TokenData.upn

            # Create an OAuth2 mechanism for authentication
            ##$oAuth2 = [MailKit.Security.SaslMechanismOAuth2]::new($AuthToken.Account.Username, $AuthToken.AccessToken)
            #$oAuth2 = New-Object MailKit.Security.SaslMechanismOAuth2 -ArgumentList $channel.Definition.username, $token.AccessToken
            $oAuth2 = New-Object MailKit.Security.SaslMechanismOAuth2 -ArgumentList $username, $token.AccessToken
            #$oAuth2 = New-Object MailKit.Security.SaslMechanismOAuthBearer -ArgumentList $username, $token.AccessToken

            Write-Debug ($oAuth2.Credentials | Out-String)
            #Write-Verbose ($oAuth2.Credentials | fl * | Out-String)

            #$smtpClient.Authenticate($oauth2Mechanism)
            $smtpClient.Authenticate($oAuth2)
            #MethodInvocationException: Exception calling "Authenticate" with "1" argument(s): "451: 4.7.0 Temporary server error. Please try again later. PRX5 [ZR2P278CA0086.CHEP278.PROD.OUTLOOK.COM 2025-03-31T01:06:59.921Z 08DD6E37F3A552D5]"

            # Create the email message (MimeMessage)
            $message = [MimeKit.MimeMessage]::new()

            # Set the 'From' address
            if (!$From){$From = $username}
            $message_from = [MimeKit.MailboxAddress]::new('Your Name', $From)
            $message.From.Add($message_from)

            # Set the 'To' address
            if (!$To){$To = $username}
            $message_to = [MimeKit.MailboxAddress]::new('Recipient Name', $To)
            $message.To.Add($message_to)

            # Set the subject and body of the email
            #$message.Subject = "Your Email Subject"
            $message.Subject = $Subject
            $messageBody = [MimeKit.TextPart]::new("plain")
            #$messageBody.Text = "This is the email body content."
            $messageBody.Text = $Body
            $message.Body = $messageBody

            # Proceed with sending email
            try {
                $smtpClient.Send($message)
            } catch {
                # MethodInvocationException: Exception calling "Send" with "1" argument(s): "5.7.57 Client not authenticated to send mail. [ZR0P278CA0195.CHEP278.PROD.OUTLOOK.COM 2025-03-31T00:59:51.228Z 08DD6FAFE0C04FAE]"
                # MethodInvocationException: Exception calling "Send" with "1" argument(s): "5.1.3 Invalid address"
                # 2.0.0 OK <IBMO05GM0QU4.0T9V1MGPDDU03@tablet-sm30s97m> [Hostname=AM8P190MB0851.EURP190.PROD.OUTLOOK.COM]
                throw "Failed to send mail: $($_.Exception.Message)"
            }

            # Disconnect after sending the email
            $smtpClient.Disconnect($True)
            $smtpClient.Dispose()


        }
        'TEAMS' {
            # --- MS Teams
            Write-Verbose "ToDevelop"

        }
        # EWS

        # SENDGRID

        default {
            Write-Debug "Invalid modus specified"
        }
    }
}