Send-MailMessage: отправка писем из PowerShell

Встроенный командлет 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>]

командлет Send-MailMessage отправки почты из powershell

Основные параметры:

  • From – адрес отправителя если SMTP сервер не проверяет адрес отправителя, то можно отправить письмо от имени любого email адреса);
  • To – email адрес получателя;
  • SMTPServer – адрес SMTP сервера , через который нужно выполнить отправку письма

Адрес SMTP сервера не обязательно указывать, если вы задали адрес почтового сервера в переменной окружения $PSEmailServer:

$PSEmailServer = "smtp.remontka.com"

Отправка письма из консоли 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.remontka.com'

Вы можете отправить письмо на один или несколько почтовых ящиков, в канал Teams или на адрес группы рассылки Exchange .

Для удобства редактирования предыдущую команду отправки можно представить так:

Send-MailMessage `
-SmtpServer smtp.remontka.com `
-To ' [email protected] ',' [email protected] ' `
-From ' [email protected] ' `
-Subject "test" `
-Body "Тема письма на русском" `
-Encoding 'UTF8'

Обратите, что в последней команде мы дополнительно указали, что нужно использовать для письма кодировку UTF8. Иначе, если тема или текст письма будут содержать русские буквы, то они будут отображены знаками вопроса.

отправка тестового письма из powershell русская кодировка

В Windows PowerShell по умолчанию используются кодировки ANSI и ASCII. Если вы обновили свою версию до PowerShell Core 7.x, имейте в виду что в этой версии по умолчанию уже используется кодировка 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.remontka.com"
Port = 25
UseSsl = $false
BodyAsHtml = $true
Encoding = “UTF8”
Attachment = “C:psreport1.txt”, “C:psreport2.txt”
}
Send-MailMessage @MailMessage -Credential $cred

В этом примере мы также заменили Display Name у получателя на “DC server”.

Вот как выглядит это письмо с HTML форматированием и вложениями в интерфейсе Outlook.

Send-MailMessage: отправка писем из PowerShell

Если вы отправляете письмо от имени общего почтового ящика Exchange/Microsoft 365 , на который вам предоставлены права SendAs , вы можете указать, чтобы его копия сохранялась в папке Отправленные/Sent этого ящика. Для этого, нужно для почтового ящика включить параметр MessageCopyForSentAsEnabled :

Set-Mailbox sharedmailbox -MessageCopyForSentAsEnabled $True

SMTP аутентификация и TLS/SSL шифрование в команде Send-MailMessage

По умолчанию командлет Send-MailMessage выполняет отправку письма через стандартный SMTP порт TCP 25. Если ваш SMTP сервер позволяет отправить письмо только по защищенному протоколу, нужно указать номер порта в атрибуте –Port (чаще всего это 465 или 587) и опцию UseSsl :

-SmtpServer 'smtp.remontka.com' -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 -remontka.com –Port 465
  • Попробуйте использовать другой SMTP порт. Например, 587 (msa) вместо 465 (smtps). Порт 587 является стандартным при использовании расширения STARTTLS.
  • Если у вас используется старая версий ОС (Windows Server 2012/Windows 8 и ниже), нужно включить поддержку протокола TLS2 для PowerShell с помощью команды:
    [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
В следующей таблице перечислены параметры SMTP серверов популярных публичных email провайдеров, которые вы можете использовать для отправки почты из PowerShell (обратите внимание, что у большинства из них нужно дополнительно разрешить отправку писем через SMTP из интерфейса аккаунта):

Название Адрес 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)

powershell Send-MailMessage отправка почты с аутентфикацией

Или вы можете сохранить имя пользователя и пароль для аутентификации на SMTP через переменную:

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

PowerShell: отправка письма через Gmail/Mail.ru/Яндекс

Для отправки письма через ваш ящик на одном из публичных почтовых сервисов вместо пароля для входа в ящик рекомендуется использовать App Password. Например, в Gmail вы можете создать App Password после того, как настроите 2 факторную аутентификацию для вашего аккаунта Google. Сгенерируйте и скопируйте ваш App password (в google это пароль из 16 символов).

app password для отправки письма через SMTP Gmail

Следующий пример показывает, как отправить письмо из 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

Обратите внимание, что при использовании этой команды ваш пароль будет сохранен в открытом виде в истории команд PowerShell . Смотри статью о том, как использовать и защищать пароли в скриптах PowerShell .

При использовании команды 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 команда устарела и не гарантирует безопасное подключение к SMTP серверу

Командлет 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 ).

EnglishRussianUkrainian