Table of Contents
Sending emails through Microsoft 365 with PowerShell
We are using the PowerShell to send emails using Microsoft 365 SMTP:
Send-MailMessage `
-To "[email protected]" `
-From "[email protected]" `
-Subject "This is a test message from PowerShell" `
-Body "Hello World!" `
-Credential $Cred `
-SmtpServer "smtp.office365.com" -Port 587 -UseSsl
The above command works fine in our test Windows 10 computer, but when we use it on our Windows servers, the code fails with an SmtpException Failure sending mail, Unable to read data from the transport connection: net_io_connectionclosed.
Send-MailMessage : Unable to read data from the transport connection: net_io_connectionclosed.
At line:1 char:1
+ Send-MailMessage `
+ ~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.Mail.SmtpClient:SmtpClient) [Send-MailMessage], SmtpException
+ FullyQualifiedErrorId : SmtpException,Microsoft.PowerShell.Commands.SendMailMessage
Enable TLS 1.2 on Windows Server
The matter is that the Microsoft 365 SMTP servers accept only TLS 1.2 for negotiating STARTTLS.
So, to use TLS 1.2 for connections to the email server from the PowerShell console, we must add the following command before executing the Send-MailMessage cmdlet:
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
Send-MailMessage `
-To "[email protected]" `
-From "[email protected]" `
-Subject "This is a test message from PowerShell" `
-Body "Hello World!" `
-Credential $Cred `
-SmtpServer "smtp.office365.com" -Port 587 -UseSsl
Now, the PowerShell script works without any error.
But it is inconvenient because:
- You must add the code before any Send-MailMessage command.
- The command only made the current PowerShell session using TLS 1.2. When you restart your server or open another PowerShell session. The issue will happened again.
So, we need to enable TLS 1.2 on our server permanently. Then even we restart your computer or restart the PowerShell session the script would work without insert any addition command.
To enable TLS 1.2 on Windows Server, simply copy/paste below commands into an elevated PowerShell then execute them at once.
Set-ItemProperty `
-Path 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\.NetFramework\v4.0.30319' `
-Name 'SchUseStrongCrypto' -Value '1' -Type DWord
Set-ItemProperty `
-Path 'HKLM:\SOFTWARE\Microsoft\.NetFramework\v4.0.30319' `
-Name 'SchUseStrongCrypto' -Value '1' -Type DWord
Below is a screenshot when we are enabling TLS 1.2 on our Windows Server 2016.
After enabled the TLS 1.2 on our Windows Server. We ran the below command to check if it works.
[Net.ServicePointManager]::SecurityProtocol
Finally, restart the PowerShell session then trying to send email using PowerShell. You should be able send email without an error or problem.