vzmon1
vzmon1

Reputation: 69

Powershell and MailKit - Fails in Script

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 protected]".Split(',').Trim()
     $from = "[email protected]"
     $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.

Upvotes: 1

Views: 2830

Answers (2)

vzmon1
vzmon1

Reputation: 69

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 = "[email protected]".Split(',').Trim()
     $from = "[email protected]"
     $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.

Upvotes: 1

filimonic
filimonic

Reputation: 4634

  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'

Upvotes: 2

Related Questions