You can use the built-in Send-MailMessage cmdlet to send SMTP e-mails from PowerShell (previously you can use the .Net System.Net.Mail
class to send e-mail messages). Send-MailMessage allows you to send messages with attachments, use HTML format for the body of the message, enable delivery notification, send a message to multiple recipients at once, etc. In this article, we’ll see how to use the Send-MailMessage
cmdlet to send e-mail messages from within your PowerShell scripts.
PowerShell Send-MailMessage Cmdlet: Parameters and Examples
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.
Here are the main options:
- From – is a sender address. You can send an email message on behalf of any email address if the SMTP server does not check the sender address (anonymous relay);
- To – the recipient’s email address;
- SMTPServer –the address of the SMTP server through which you want to send the 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 with the specified subject and body to multiple recipients.
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 the UTF8 encoding for the email. Otherwise, if the email subject or body contains non-ANSI characters, they will be displayed incorrectly.
You can specify multiple recipients by using the parameters:
To
– the regular recipient’s email addresses;Cc
– the email addresses to send a carbon copy (CC) of the email message;Bcc
– the e-mail addresses that will receive a copy of the e-mail but will not be listed as a recipient of the message.
You can enable a delivery notification for an email using -DeliveryNotificationOptions (which allows you to be notified when the recipient receives an email). The notification types available are:
- OnSuccess (Notify if the delivery is successful)
- OnFailure (Notify if the delivery is unsuccessful)
- Delay (Notify if the delivery is delayed)
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 an attachment to your email, use the -Attachments option. In the example below, we are going to send an e-mail in the HTML format (-BodyAsHtml) and attach file1.txt and report.xsls from the 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 have also replaced the recipient’s display name with “DC server”.
Here is how the HTML email with attachments looks in the Gmail interface.
Set-Mailbox it_dept -MessageCopyForSentAsEnabled $True
Using Send-MailMessage with SMTP Auth and TLS/SSL
By default, the Send-MailMessage cmdlet sends an e-mail via the default unencrypted SMTP port TCP 25. If your SMTP server allows sending e-mail only using an encrypted protocol, you can specify the port number in the -Port attribute (most often it is 465 or 587) and the –UseSsl option:
-SmtpServer 'smtp.woshub.com' -Port 465 –UseSsl
An error will occur if the SMTP server’s SSL certificate doesn’t match the FQDN specified in the HELO:
Send-MailMessage: The remote certificate is invalid according to the validation procedure.
You may also receive an error when sending an 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 (smtps). 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 must enable TLS 1.2 protocol support for PowerShell by using the command:
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
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 is denied), you will 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 to the SMTP server using the -Credential option.
You can interactively prompt for the user’s credentials for authentication:
Send-MailMessage …… -Credential (Get-Credential)
You can also specify the account credentials to use for authentication in the variable:
$cred = Get-Credential
Send-MailMessage ... -Credential $cred
How to Send an Email via the Gmail SMTP with PowerShell?
To send an email from your mailbox on one of the public mail services, it is recommended that you use an App Password instead of a password to access your account/mailbox. For example, in Gmail, you can create an app password after you enable the two-factor authentication for your Google Account. Generate and copy your app password on Google (it’s a 16-character password).
The following example shows how to send an email from your Google mailbox using PowerShell. You must use the App Password instead of your Google account password. In this example, we will specify the app password for connecting 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 new 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 https://aka.ms/SendMailMessage for more information.
The Send-MailMessage cmdlet uses the .NET SmtpClient class that doesn’t support modern authentication methods, including Microsoft Modern Authentication. It is recommended that you use the Graph API to send emails from PowerShell through the Microsoft 365/Exchange Online (by using the Send-MgUserMail
cmdlet or Invoke-RestMethod
to call the sendMail method via the REST API).
8 comments
Thanks a lot. i get clarity on this page even gothrough same query on multiple site
There is a much simpler way to send email from the command line:
https://sourceforge.net/projects/mail-alert/
Simpler? Questionable.
An executable from “adam” in a corporate environment? Unlikely.
Salve due richieste :
-c’è un modo per far si che una volta che l’utente si è loggato o ha fatto il logoff ma per ipotesi ci fosse assenza di rete e quindi no internet, il sistema provi a inviare lo stesso l’email ma non trovando modo di inviarla perchè internet assente la tenga in coda finche la connessione non viene ripristinata anche per esempio il giorno successivo?
-quando spengo il pc non fa in tempo a mandare l’email perchè il sistema disconnette subito la rete ,come si puo’ fare per far si che windows non disabiliti la rete allo spegnimento finche prima non è stata inviata l’email?
Grazie
Hi, two requests:
-is there a way to ensure that once the user is logged in or has logged off but hypothetically there was no network and therefore no internet, the system tries to send the email anyway but cannot find way to send it because the internet is absent keep it in the queue until the connection is restored also for example the next day?
-when I turn off the pc it doesn’t have time to send the email because the system immediately disconnects the network, how can you do to ensure that windows does not disable the network on shutdown until the email has been sent first?
Thank you
How can I make PowerShell stopping asking for the password?, I need my process to run in a job.
Thank you in advance
Just use command line tool Mail Alert Simple Mailer (https://sourceforge.net/projects/mail-alert/) and forget about password prompts. Your mail server password will be stored in encrypted form, so it is much safer solution then PowerShell script.
You can pass the credential object directly to the Send-MailMessage command:
Send-MailMessage ..... -credential (new-object System.Net.NetworkCredential("user1","pass1","domain"))'