Behind the PowerShell Pipeline logo

Behind the PowerShell Pipeline

Archives
Log in
Subscribe
July 7, 2026

Delivering a PowerShell Mail Solution

In this issue:

  • Attachments
  • Managing Configuration Data
    • Export-SmtpConfiguration
    • Import-SmtpConfiguration
  • New-SmtpClient
  • Send-jhMailMessage
  • Module Scoping
  • Summary

At the end of last month I shared my solution for the May 2026 scripting challenge. We've been looking at PowerShell code to send mail messages. We're getting close to having a complete solution. Let's wrap things up today by addressing a few items left to be handled. Remember, the process of creating the solution is more valuable than the solution itself.

Attachments

Once again, we'll need a mail message object.

$to = "jhicks91@yahoo.com"
$from = "jhicks@jdhitsolutions.com"
$msg = [System.Net.Mail.MailMessage]::new($from, $to, 'Attach Demo', 'This is a test email with attachments')

The $msg object has an Attachments property.

PS C:\> $msg | Get-Member Attachments

   TypeName: System.Net.Mail.MailMessage

Name        MemberType Definition
----        ---------- ----------
Attachments Property   System.Net.Mail.AttachmentCollection Attachments {get;}

PS C:\> Get-TypeMember System.Net.Mail.AttachmentCollection

   Type: System.Net.Mail.AttachmentCollection

Name    MemberType ResultType IsStatic IsEnum
----    ---------- ---------- -------- ------
GetType Method     Type
Count   Property   Int32
Item    Property   Attachment

Get-TypeMember shows this to be a collection of Attachment objects.

PS C:\> Get-TypeMember System.Net.Mail.Attachment

   Type: System.Net.Mail.Attachment

Name                       MemberType ResultType         IsStatic IsEnum
----                       ---------- ----------         -------- ------
CreateAttachmentFromString Method     Attachment             True
GetType                    Method     Type
ContentDisposition         Property   ContentDisposition
ContentId                  Property   String
ContentStream              Property   Stream
ContentType                Property   ContentType
Name                       Property   String
NameEncoding               Property   Encoding
TransferEncoding           Property   TransferEncoding              True

There's more to this than I would have expected. How I create one?

PS C:\> Get-TypeConstructor System.Net.Mail.Attachment

[System.Net.Mail.Attachment]::new([System.String]$fileName)

[System.Net.Mail.Attachment]::new([System.String]$fileName,
[System.String]$mediaType)

[System.Net.Mail.Attachment]::new([System.String]$fileName,
[System.Net.Mime.ContentType]$contentType)

[System.Net.Mail.Attachment]::new([System.IO.Stream]$contentStream,
[System.String]$Name)

[System.Net.Mail.Attachment]::new([System.IO.Stream]$contentStream,
[System.String]$Name,
[System.String]$mediaType)

[System.Net.Mail.Attachment]::new([System.IO.Stream]$contentStream,
[System.Net.Mime.ContentType]$contentType)

There's most likely more here than I need. A simple file path seems sufficient.

PS C:\> [System.Net.Mail.Attachment]::new("c:\work\procs.txt")

Name               : procs.txt
NameEncoding       :
ContentDisposition : attachment
ContentStream      : System.IO.FileStream
ContentId          : e1ce4e6a-7472-462b-85cb-554614f7a6c9
ContentType        : application/octet-stream; name=procs.txt
TransferEncoding   : Base64

Because it is a collection, there is most likely an implicit Add() method. Based on what I've seen, if I add a file path as an attachment, PowerShell will handle the rest.

PS C:\> $msg.Attachments.Add("c:\work\procs.txt")
PS C:\> $msg.Attachments

Name               : procs.txt
NameEncoding       :
ContentDisposition : attachment
ContentStream      : System.IO.FileStream
ContentId          : d6fcc1a4-874f-4603-89b9-7d92b5ab4957
ContentType        : application/octet-stream; name=procs.txt
TransferEncoding   : Base64

All that remains is to use the SmtpMailClient to send the message.

$mc.send($msg)
Sending an attachment
figure 1
Want to read the full issue?
Already a paid subscriber? Click here to log in.
GitHub
Bluesky
LinkedIn
Mastodon
jdhitsolutions.github.io
Powered by Buttondown, the easiest way to start and grow your newsletter.