1

I'm attempting to use the new MailKit / Mimekit instead of Send-MailMessage in Powershell. I found Send-MailKitMessage 1.0.1 on the Powershell Gallery

My needs are simple and the Powershell will be used for internal alerts only, so I simplified the code to suit my needs.

    ***using namespace MailKit
       using namespace MimeKit
    
         $emailDLL = "F:\Apps\Email\MailKit.dll"
         $mimeDll = "F:\Apps\Email\MimeKit.dll"
         Add-Type -Path $emailDLL
         [System.Reflection.Assembly]::LoadFile($mimeDll)
              

#extend classes to be available to the calling script (MimeKit assembly is loaded first from the manifest file so is available when this module loads) class MailboxAddressExtended : MailboxAddress { #does not allow parameterless construction MailboxAddressExtended([string]$Name, [string]$Address ) : base($Name, $Address) { [string]$Name, #can be null [string]$Address #cannot be null } }

        class InternetAddressListExtended : InternetAddressList {}
        $List = New-Object InternetAddressListExtended # of type MimeKit.InternetAddress
    
         $smtpClient = New-Object MailKit.Net.Smtp.SmtpClient
     
         $message = [MimeKit.MimeMessage]::new()
         $TextPart = [MimeKit.TextPart]::new("html")
    
     #endregion
    
     [string[]]$recipients = "email@testdomain.com".Split(',').Trim()
     $from = "Dev_Test@testdomain.com"
     $smtpSvr = '190.132.148.22'
     $smtpPort = 25

function sendEmail ($subjectline,$msgbody) {
    $message.From.Add($from)  
    foreach ($address in $recipients) {$List.Add($address)}
    $message.To.AddRange($List)
    $TextPart.Text = $msgbody
    $message.Body = $TextPart
    $message.Subject = $subjectline
    
    if(!$smtpClient.IsConnected) {
    $smtpClient.Connect($smtpSvr)
    }
    if ($smtpClient.IsConnected) {
        $smtpClient.Send($message)
        $smtpClient.Disconnect($true)
        
    }***

 }

When I run the above code in a PS1 script, I get an error:

Unable to find type [MailboxAddress]

I can manually enter the same code in a Powershell window and it works as expected. I have used PS5 v5.1, PS7 v7.1 and I get the same error. I went with the above code since it allowed me to send emails to more than one individual / group. While relatively new to Powershell, I was able to work through all the previous issues to come up with the above code.

I greatly appreciate any guidance that can be provided.

vzmon1
  • 69
  • 5

2 Answers2

2
  1. Send-MailKitMessage is a comlete module that should be installed. Follow here
  2. Types like [MailboxAddress] ( [MimeKit.MailboxAddress] ) are expected to be load from DLL files, but if you use only PSM1 file, there are no DLLs to load this from.
  3. It's 3.1.0 version currently (as for 2021-03-04)
  4. It (v3.1.0) works only on PowerShell 7+, because it uses ternary operator whick was introduced is PSv7. I think it can be easily fixed to port back to PSv5, but this requires testing.
  5. If you don't want to install module, download nupkg file, unzip it using 7zip and try using like this:

Import-Module -Name 'C:\...\send-mailkitmessage.3.1.0\Send-MailKitMessage.psd1'

or like this:

[System.Reflection.Assembly]::LoadFile('C:\...\send-mailkitmessage.3.1.0\Libraries\BouncyCastle.Crypto.dll')
[System.Reflection.Assembly]::LoadFile('C:\...\send-mailkitmessage.3.1.0\Libraries\MailKit.dll')
[System.Reflection.Assembly]::LoadFile('C:\...\send-mailkitmessage.3.1.0\Libraries\MimeKit.dll')
Import-Module -Name 'C:\...\send-mailkitmessage.3.1.0\Send-MailKitMessage.psm1'
filimonic
  • 3,988
  • 2
  • 19
  • 26
  • I download the latest Send-MailKitMessage, manually loaded the files per the recommendations. I then created the needed variables & Parameter struct and loaded into window. I was able to send-MailkitMessage Parameters successfully. I put the same commands into PS1 file, minus send-MailkitMessage Parameters and it launches okay. But when I run send-MailkitMessage Parameters in window it can't see $HTMLBody, all variable parameters are in the PS1 file. Prior to running Send, I can see the info in variables, after Send they are empty. FYI: I omitted the AT sign in mod signature – vzmon1 Mar 04 '21 at 22:43
1

Although I made some progress attempting to incorporate Send-MailkitMessage, I continued to encounter unexpected errors. I decided to go back to basics since my needs were basics and I was sending out internal Alerts emails only. I created this test PS1 file:

using namespace MailKit 
using namespace MimeKit

     $emailDLL = "F:\Apps\Email\MailKit.dll"
     $mimeDll = "F:\Apps\Email\MimeKit.dll"
     Add-Type -Path $emailDLL
        
     [System.Reflection.Assembly]::LoadFile($mimeDll)
     [System.Reflection.Assembly]::LoadFile($emailDLL)

        class MailboxAddressExtended : MailboxAddress { #does not allow parameterless construction
        MailboxAddressExtended([string]$Name, [string]$Address ) : base($Name, $Address) {
            [string]$Name,      #can be null
            [string]$Address    #cannot be null
        }
    } 

    class InternetAddressListExtended : InternetAddressList {}
    $List = New-Object InternetAddressListExtended # of type MimeKit.InternetAddress

     $message = [MimeKit.MimeMessage]::new()
     $TextPart = [MimeKit.TextPart]::new("html")

     [string[]]$recipients = "name@company.net".Split(',').Trim()
     $from = "Dev_Mailkit@company.net"
     $smtpSvr = 'xxx.xxx.xxx.xxx'
     $smtpPort = 25

     $message.From.Add($from)  
       foreach ($address in $recipients) {$List.Add($address)}
       $message.To.AddRange($List)

        $smtpClient = New-Object MailKit.Net.Smtp.SmtpClient

      $TextPart.Text = "Mailkit Test 30000"
      $message.Body = $TextPart
      $message.Subject = "Another Test" 

      if(!$smtpClient.IsConnected) {
    $smtpClient.Connect($smtpSvr)
    }
    if ($smtpClient.IsConnected) {
        $smtpClient.Send($message)
        $smtpClient.Disconnect($true)
        
    }```

@filimonic  I greatly appreciate the feedback, which is how I was able to overcome my initial obstacles.
vzmon1
  • 69
  • 5