Встроенный командлет Send-MailMessage можно использовать для отправки email писем из PowerShell. Данный встроенный командлет доступен для отправки почтовых email сообщений в PowerShell начиная с версии 2.0 (командлет применяется вместо класса .Net System.Net.Mail). Send-MailMessage позволяет отправить через SMTP сервер письма с вложениями, использовать HTML формат для тела письма, включить уведомления о доставке, отправить письмо сразу нескольким получателям и т.д. В этой статье мы рассмотрим, как использовать Send-MailMessage для отправки email сообщений из ваших скриптов PowerShell.
Для получения базовой информации о синтаксисе командлета, выполните команду:
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>]
Основные параметры:
- From – адрес отправителя если SMTP сервер не проверяет адрес отправителя, то можно отправить письмо от имени любого email адреса);
- To – email адрес получателя;
- SMTPServer – адрес SMTP сервера , через который нужно выполнить отправку письма
Адрес SMTP сервера не обязательно указывать, если вы задали адрес почтового сервера в переменной окружения $PSEmailServer:
$PSEmailServer = "smtp.winitpro.ru"
Отправка письма из консоли PowerShell с помощью командлета Send-MailMessage
Следующая команда PowerShell отправит письмо с указанной темой (Subject) и содержимым (Body) нескольким получателям.
Send-MailMessage -From '[email protected]' -To '[email protected]','[email protected]' -Subject "Alert from Server1" -Body "It is email body" –SmtpServer 'smtp.winitpro.ru'
Для удобства редактирования предыдущую команду отправки можно представить так:
Send-MailMessage `
-SmtpServer smtp.winitpro.ru `
-To '[email protected]','[email protected]' `
-From '[email protected]' `
-Subject "test" `
-Body "Тема письма на русском" `
-Encoding 'UTF8'
Обратите, что в последней команде мы дополнительно указали, что нужно использовать для письма кодировку UTF8. Иначе, если тема или текст письма будут содержать русские буквы, то они будут отображены знаками вопроса.
Вы можете задать нескольких получателей с помощью параметров:
-
To
— обычные получатели; -
Cc
– получатели копии письма; -
Bcc
— получатели скрытой копии.
Вы можете включить для письма уведомление о доставке с помощью параметра -DeliveryNotificationOption. Возможные значения:
- OnSuccess (отчет при удачной доставке);
- OnFailure (отчет если доставка не выполнена);
- Delay (оповестить, если доставка отложена).
В одной команде можно указать сразу несколько опций:
Send-MailMessage … -DeliveryNotificationsOptions 'OnSuccess', 'OnFailure'
Уведомление о доставки будет отправлено в почтовый ящик, указанный в поле -From.
Также вы можете задать приоритет письма (отображается не во всех клиентах):
-Priority High|Low|Normal
Если нужно добавить в письмо вложение, используйте параметр -Attachments. В следующем примере мы отправим письмо в формате HTML (параметр -BodyAsHtml) и прикрепим к письму файлы report1.txt и report2.txt с локального диска:
$MailMessage = @{
To = "[email protected]
Bcc = "[email protected]", "[email protected]"
From = "DC server <[email protected]>"
Subject = "Отчет с сервера DC"
Body = "<h1>Добро пожаловать!</h1> <p><strong>Сформировано:</strong> $(Get-Date -Format g)</p>”
Smtpserver = "smtp.winitpro.ru"
Port = 25
UseSsl = $false
BodyAsHtml = $true
Encoding = “UTF8”
Attachment = “C:\ps\report1.txt”, “C:\ps\report2.txt”
}
Send-MailMessage @MailMessage -Credential $cred
В этом примере мы также заменили Display Name у получателя на “DC server”.
Вот как выглядит это письмо с HTML форматированием и вложениями в интерфейсе Outlook.
Set-Mailbox sharedmailbox -MessageCopyForSentAsEnabled $True
SMTP аутентификация и TLS/SSL шифрование в команде Send-MailMessage
По умолчанию командлет Send-MailMessage выполняет отправку письма через стандартный SMTP порт TCP 25. Если ваш SMTP сервер позволяет отправить письмо только по защищенному протоколу, нужно указать номер порта в атрибуте –Port (чаще всего это 465 или 587) и опцию UseSsl:
-SmtpServer 'smtp.winitpro.ru' -Port 465 –UseSsl
Если SSL сертификат SMTP сервера не соответствует FQDN, указанному в HELO то появится ошибка:
Send-MailMessage: The remote certificate is invalid according to the validation procedure.
При отправке письма с помощью шифрования SSL/TLS также может появится ошибка:
Send-MailMessage : Unable to read data from the transport connection: net_io_connectionclosed
В этом случае рекомендуется проверить
- Что указанный порт доступен:
Test-NetConnection -winitpro.ru –Port 465
- Попробуйте использовать другой SMTP порт. Например, 587 (msa) вместо 465 (smtps). Порт 587 является стандартным при использовании расширения STARTTLS.
- Если у вас используется старая версий ОС (Windows Server 2012/Windows 8 и ниже), нужно включить поддержку протокола TLS2 для PowerShell с помощью команды:
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
Название | Адрес SMTP сервера | Порт | Тип шифрования |
Yandex | smtp.yandex.ru | 465 | TLS/SSL |
Mail.ru | smtp.mail.ru | 465 | TLS/SSL |
Gmail | smtp.gmail.com | 587 25 465 | TLS TLS SSL |
Office 365 | smtp.office365.com | 587 | TLS |
Outlook.com | smtp-mail.outlook.com | 587 | TLS |
Если SMTP сервер запрещает анонимную отправку (запрещен relay), то при попытке отправить письмо вы получите ошибку:
5.7.1 Client was not authenticated.
Или:
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.
В этом случае вы можете аутентифицироваться на SMTP сервере с помощью параметра –Credential.
Можно интерактивно запросить данные пользователя для аутентификации
Send-MailMessage …… -Credential (Get-Credential)
Или вы можете сохранить имя пользователя и пароль для аутентификации на SMTP через переменную:
$cred = Get-Credential
Send-MailMessage ... -Credential $cred
PowerShell: отправка письма через Gmail/Mail.ru/Яндекс
Для отправки письма через ваш ящик на одном из публичных почтовых сервисов вместо пароля для входа в ящик рекомендуется использовать App Password. Например, в Gmail вы можете создать App Password после того, как настроите 2 факторную аутентификацию для вашего аккаунта Google. Сгенерируйте и скопируйте ваш App password (в google это пароль из 16 символов).
Следующий пример показывает, как отправить письмо из PowerShell из вашего ящика Google. Вместо пароля вашего аккаунта нужно использовать App Password. В этом примере мы сохраним пароль для подключения к SMTP серверу непосредственно в коде скрипта PowerShell.
$From = "[email protected]"
$To = "[email protected]"
$Subject = "Test message subject from $($env:computername)"
$Body = "Email text"
$Password = "yourgoogleapppassword" | 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
При использовании команды Send-MailMessage в новых версиях 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.
Командлет Send-MailMessage использует .NET класс SmtpClient для отправки писем, которые не поддерживает современные методы проверки подлинности, в том числе Microsoft Modern Authentication. В Microsoft 365/Exchange Online для отправки писем из PowerShell рекомендуется использовать Graph API, например, командлет
Send-MgUserMai
l или
Invoke-RestMethod
для вызова метода sendMail в REST API (подробнее в статье PowerShell: Отправка писем через Microsoft Graph API).