Lately I seem to run into such questions quite often, so I figured I’d put a short article outlining the most common issues one might run into when using PowerShell to send email messages via SMTP AUTH in Office 365. The article is by no means intended to be an exhaustive resource for all possible errors, just some of the common things I see over at the different communities.
One issue that seems to be overlooked in particular is the fact that PowerShell by default uses on older/insecure protocols. More correctly, it uses the system default values, which even for modern (desktop) OS versions are a bit relaxed. By now, you should probably be well aware that within Office 365, Microsoft has more strict requirements, and generally speaking you should be using TLS 1.2. This in turn creates problems with PowerShell, as connections negotiated via older/less secure protocols will get blocked. The error message received simply says something like “the server requires a secure connection” but doesn’t directly tell you what to do:
Send-MailMessage: 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 [VI1PR08CA0220.eurprd08.prod.outlook.com]
So, one thing to try, and make habit of is to configure the Security Protocol value and set it to TLS1.2. This can be done by invoking the corresponding method, as follows:
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
Once this is done, you can retry running the Send-MailMessage cmdlet and if the credentials specified are correct, it should work OK. Granted, there are several other things you might need to check on or configure before you can make it work, which we will cover next. But first, let’s answer another question that pops up – how can we make sure the changes to the Security Protocol value persist (they’re per-session ones). An easy way to do this is to add the line above to your PowerShell profile. Remember that profiles can depend on the host as well, so consult the above article to pick the best location for your scenario.
If the above suggestion doesn’t solve the issue, one other thing to check is whether SMTP Auth is disabled for your organization or the particular user. As the article explains, per-mailbox settings take precedence over the organizational config, so if needed you can add exceptions, either by using the UI or PowerShell:
Set-CASMailbox -Identity email@example.com -SmtpClientAuthenticationDisabled $true
Another thing to remember is that the current implementation of SMTP Auth uses basic authentication, and thus is considered insecure. Newer PowerShell versions might even warn you about this when using the Send-MailMessage cmdlet:
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.
Microsoft has already announced support for using OAuth with SMTP, but that doesn’t mean the already existing clients/libraries will be able to leverage this automatically. They still rely on and will try to use Basic authentication, which by now should be blocked across most Office 365 tenants. The Security defaults feature is one example on how this block can be enforced, and depending on the SKU you might be able to leverage Conditional Access policies or Exchange Authenticated policies for more granular control over this. So make sure to check your appropriate controls and exclude any accounts that need to leverage outdated methods to send email, such as using the Send-MailMessage cmdlet in PowerShell.
Of course one also must make sure that the credentials are correct, and for best results, use an account that has a corresponding Exchange Online license assigned. Should you need to impersonate other users when sending messages, the Send-MailMessage cmdlet is probably not the best approach (use EWS instead), but it might work in some cases, granted you make sure the relevant Send As permissions have been assigned.