Send-MailMessage: Sending E-mail with PowerShell | Ranjan.info

you can use the built-in send-mail message Cmdlet to send SMTP e-mail from PowerShell. You can use this cmdlet to send e-mail in PowerShell version 2.0 and newer (previously you could use .Net System.Net.Mail class to send e-mail messages). Send-MailMessage allows you to send messages with attachments, use HTML format for the message body, enable delivery notification, send a message to multiple recipients at once, and more. In this article, we will see how to use Send-MailMessage cmdlet to send email messages from within your PowerShell script.

PowerShell Send-MailMessage Cmdlet: Parameters and Example

To get the syntax of the cmdlet, run this command:

get-help Send-MailMessage

Send-MailMessage [-To] <String[]> [-Subject] <String> [[-Body] <String>] [[-SmtpServer] <String>] [-Attachments <String[]>] [-Bcc <String[]>] [-BodyAsHtml] [-Cc <String[]>] [-Credential <PSCredential>] [-DeliveryNotificationOption {None | OnSuccess | OnFailure | Delay | Never}] [-Encoding <Encoding>] -From <String> [-Port <Int32>] [-Priority {Normal | Low | High}] [-UseSsl] [<CommonParameters>]
The Send-MailMessage cmdlet sends an email message from within Windows PowerShell.

Using the PowerShell Send-MailMessage cmdlet

Here are the main options:

  • From – Sender’s address. You can send an email message on behalf of any email address if the SMTP server does not check the sender’s address (anonymous relay);
  • To – Recipient’s Email Address;
  • SMTPServer – The address of the SMTP server through which you want to send e-mail.

The SMTP server address is not required if you set the mail server address in the $PSEmailServer environment variable:

$PSEmailServer = "smtp.woshub.com"

The following PowerShell command will send an e-mail to multiple recipients with the specified subject and body.

Send-MailMessage -From '[email protected]' -To '[email protected]','[email protected]' -Subject "Test Email Alert" -Body "This is email body text" –SmtpServer 'smtp.woshub.com'

To make it easier to edit the attributes of a cmdlet, the Send-MailMessage command can be represented as follows:

Send-MailMessage `
-SmtpServer smtp.woshub.com `
-To '[email protected]','[email protected]' `
-From '[email protected]' `
-Subject "Test" `
-Body "Sending email using PowerShell" `
-Encoding 'UTF8'

Note that in the last command, we additionally set utf8 Encoding for email. Otherwise, if the email subject or body contains non-ANSI characters, they will be displayed incorrectly.

You can specify multiple recipients using parameters:

  • To – email addresses of regular recipients;
  • Cc – email addresses to send carbon copies (cc) of email messages;
  • Bcc – E-mail addresses that will receive a copy of the e-mail but will not be listed as recipients of the message.

You can enable delivery notification using email -Delivery notification option (Which allows the recipient to notify you when the email is received). Available notification types are:

  • onSuccess (Notify if delivery is successful)
  • on failure (Notify in case of delivery failure)
  • delay (Notify in case of delivery delay)

You can specify multiple options in one command:

Send-MailMessage … -DeliveryNotificationsOptions 'OnSuccess', 'OnFailure'

The delivery notification will be sent to the mailbox that is specified in the “From” field.

You can also set the priority of the email message (not shown in some clients):

-Priority High|Low|Normal

If you want to add attachment to your email, use -attachment Option. In the below example, we are going to send an e-mail in HTML format (-BodyAsHtml) and append file1.txt And report.xsls from local drive.

$MailMessage = @{
To = "[email protected]"
Bcc = "[email protected]", "[email protected]"
From = "DC server <[email protected]>"
Subject = "DC Server Report"
Body = "<h1>Welcome!</h1> <p><strong>Generated:</strong> $(Get-Date -Format g)</p>”
Smtpserver = "smtp.gmail.com"
Port = 587
UseSsl = $true
BodyAsHtml = $true
Encoding = “UTF8”
Attachment = “C:\Logs\file1.txt”, “C:\Logs\report.xlsx”
}
Send-MailMessage @MailMessage -Credential $cred

In this example, we’ve replaced the display name of the recipient with “DC Server”.

Here’s how an HTML email with an attachment looks like in the Gmail interface.

A test email with an attachment generated with PowerShell in the Gmail interface

When you send an email on behalf of an Exchange/Microsoft 365 shared mailbox for which you have been given permission Send permissions, you can specify that a copy of the message should be saved in the Sent Items folder of the source mailbox. For that, enable MessageCopyForSentAsEnabled Parameters for mailbox:

Set-Mailbox it_dept -MessageCopyForSentAsEnabled $True

Using Send-MailMessage with SMTP Authentication and TLS/SSL

By default, the Send-MailMessage cmdlet sends an e-mail through the default unencrypted SMTP port TCP 25. If your SMTP server allows sending e-mail using only encrypted protocols, you can specify the port number -port specialty (most often it is 465 or 587) and –use ssl Option:

-SmtpServer 'smtp.woshub.com' -Port 465 –UseSsl

If the SMTP server’s SSL certificate does not match the FQDN specified in HELO, an error will occur:

Send-MailMessage: The remote certificate is invalid according to the validation procedure.

You may also receive the error when sending email using SSL/TLS encryption:

Send-MailMessage : Unable to read data from the transport connection: net_io_connectionclosed

In this case, it is recommended that you check the following

  • That the specified SMTP port is open and accessible from your computer: Test-NetConnection smtp.woshub.com –Port 465
  • Try a different SMTP port. For example, 587 (MSA) instead of 465 (SMTP). Port 587 is the default when using the STARTTLS extension;
  • If you are using an older operating system (Windows Server 2012/Windows 8 and below), you need to enable TLS 1.2 protocol support for PowerShell using the command:
    [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
The table below lists the SMTP server settings for popular public e-mail providers that you can use to send messages from PowerShell (note that you will need to allow sending e-mail via SMTP in the account interface .):

Name SMTP Server Address port encryption type
Gmail smtp.gmail.com 587

25

465

tls

tls

ssl

Microsoft (Office) 365 smtp.office365.com 587 tls
outlook.com smtp-mail.outlook.com 587 tls
Yahoo smtp.mail.yahoo.com 587 tls
icloud mail smtp.mail.me.com 587 tls
aol smtp.aol.com 465 ssl

If the SMTP server doesn’t allow anonymous email (relay denied), you’ll see this error:

5.7.1 Client was not authenticated.

Or:

The SMTP server requires a secure connection or the client was not authenticated. The server response was: 5.7.57 SMTP; Client was not authenticated to send anonymous mail during MAIL FROM.

Then you can authenticate with the SMTP server using -credential Option.

You can interactively prompt for the user’s credentials for authentication:

Send-MailMessage …… -Credential (Get-Credential)

Send Authenticated SMTP with PowerShell Send-MailMessage

You can also specify the account credentials to use for authentication in a variable:

$cred = Get-Credential
Send-MailMessage ... -Credential $cred

How to send email via Gmail SMTP with PowerShell?

To send an email from your mailbox on one of the public mail services, it is recommended that you use a app password instead of a password to access your account/mailbox. For example, in Gmail, you can create an app password for your Google Account after you enable two-factor authentication. Generate and copy your app password on Google (this is a 16-character password).

generate smtp app password in gmail

The following example shows how to send email from your Google mailbox using PowerShell. You should use an app password instead of your Google Account password. In this example, we’ll specify the app password to connect to the Gmail SMTP server directly in the PowerShell script code.

$From = "[email protected]"
$To = "[email protected]"
$Subject = "Test PowerShell email from $($env:computername)"
$Body = "some message test "
$Password = "your_google_app_password" | ConvertTo-SecureString -AsPlainText -Force
$Credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $From, $Password
Send-MailMessage -From $From -To $To -Subject $Subject -Body $Body -SmtpServer "smtp.gmail.com" -port 587 -UseSsl -Credential $Credential

A warning is displayed when you use the Send-MailMessage command in newer versions of PowerShell Core 7.x:

WARNING: The command 'Send-MailMessage' is obsolete. This cmdlet does not guarantee secure connections to SMTP servers. While there is no immediate replacement available in PowerShell, we recommend you do not use Send-MailMessage at this time. See  for more information.

PowerShell command send-mailmessage is deprecated

The Send-MailMessage cmdlet uses the .NET SmtpClient class that does not support modern authentication methods, including Microsoft Modern Authentication. It is recommended that you use the Graph API to send email from PowerShell via Microsoft 365/Exchange Online (using Send-MgUserMail cmdlet or Invoke-RestMethod to call send mail method via REST API).

Leave a Comment