Send-MailMessage:使用 PowerShell 发送电子邮件
您可以使用内置的发送邮件消息cmdlet 从 PowerShell 发送 SMTP 电子邮件(以前您可以使用 .NetSystem.Net.Mail发送电子邮件的类)。 Send-MailMessage 允许您发送带有附件的邮件、使用 HTML 格式作为邮件正文、启用送达通知、一次向多个收件人发送邮件等。在本文中,我们将了解如何使用Send-MailMessage用于从 PowerShell 脚本内发送电子邮件的 cmdlet。
内容:
- PowerShell Send-MailMessage Cmdlet:参数和示例
- 将 Send-MailMessage 与 SMTP 身份验证和 TLS/SSL 结合使用
- 如何使用 PowerShell 通过 Gmail SMTP 发送电子邮件?
要获取 cmdlet 的语法,请运行以下命令:
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.

以下是主要选项:
- 从– 是发件人地址。如果 SMTP 服务器不检查发件人地址(匿名中继),您可以代表任何电子邮件地址发送电子邮件;
- 到– 收件人的电子邮件地址;
- SMTP服务器–您要通过其发送电子邮件的 SMTP 服务器的地址。
如果在 $PSEmailServer 环境变量中设置邮件服务器地址,则不需要 SMTP 服务器地址:
$PSEmailServer = "smtp.woshub.com"
以下 PowerShell 命令将向多个收件人发送具有指定主题和正文的电子邮件。
Send-MailMessage -From '[email protected]' -To '[email protected]','[email protected]' -Subject "Test Email Alert" -Body "This is email body text" –SmtpServer 'smtp.woshub.com'
您可以将电子邮件发送到一个或多个收件人邮箱、Teams 频道或 Exchange 通讯组中的地址。
为了更轻松地编辑 cmdlet 的属性,Send-MailMessage 命令可以表示如下:
Send-MailMessage `
-SmtpServer smtp.woshub.com `
-To '[email protected]','[email protected]' `
-From '[email protected]' `
-Subject "Test" `
-Body "Sending email using PowerShell" `
-Encoding 'UTF8'
请注意,在最后一个命令中,我们还设置了UTF8电子邮件的编码。否则,如果电子邮件主题或正文包含非 ANSI 字符,它们将无法正确显示。
Windows PowerShell 默认使用 ANSI 和 ASCII 编码。如果您已将 PS 版本更新到 PowerShell Core,请记住该版本已默认使用 UTF-8 编码。
您可以使用以下参数指定多个收件人:
To– 常规收件人的电子邮件地址;Cc– 用于发送电子邮件抄送 (CC) 的电子邮件地址;Bcc– 将接收电子邮件副本但不会被列为消息收件人的电子邮件地址。
您可以使用以下命令启用电子邮件的送达通知- 交货通知选项(这样您就可以在收件人收到电子邮件时收到通知)。可用的通知类型有:
- 论成功(发货成功通知)
- 失败时(如发货不成功请通知)
- 延迟(如发货延迟请通知)
您可以在一个命令中指定多个选项:
Send-MailMessage … -DeliveryNotificationsOptions 'OnSuccess', 'OnFailure'
送达通知将发送至“发件人”字段中指定的邮箱。
您还可以设置电子邮件的优先级(在某些客户端中不显示):
-Priority High|Low|Normal
如果您想在电子邮件中添加附件,请使用- 附件选项。在下面的示例中,我们将以 HTML 格式发送一封电子邮件 (-BodyAsHtml)并从本地驱动器附加 file1.txt 和 report.xsls。
$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:Logsfile1.txt”, “C:Logsreport.xlsx”
}
Send-MailMessage @MailMessage -Credential $cred
在此示例中,我们还将收件人的显示名称替换为“DC 服务器”。
以下是带有附件的 HTML 电子邮件在 Gmail 界面中的外观。


当您代表已被授予 SendAs 权限的 Exchange/Microsoft 365 共享邮箱发送电子邮件时,您可以指定应将邮件的副本保存在源邮箱的“已发送邮件”文件夹中。为此,请启用已启用消息复制发送方式邮箱参数:
Set-Mailbox it_dept -MessageCopyForSentAsEnabled $True
将 Send-MailMessage 与 SMTP 身份验证和 TLS/SSL 结合使用
默认情况下,Send-MailMessage cmdlet 通过默认的未加密 SMTP 端口 TCP 25 发送电子邮件。如果您的 SMTP 服务器允许仅使用加密协议发送电子邮件,则可以在-港口属性(最常见的是 465 或 587)和 –使用SSL选项:
-SmtpServer 'smtp.woshub.com' -Port 465 –UseSsl
如果 SMTP 服务器的 SSL 证书与 HELO 中指定的 FQDN 不匹配,则会出现错误:
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
在这种情况下,建议您检查以下内容
- 指定的 SMTP 端口已打开并且可以从您的计算机访问:
Test-NetConnection smtp.woshub.com –Port 465 - 尝试不同的 SMTP 端口。例如,587 (msa) 而不是 465 (smtps)。使用 STARTTLS 扩展时,端口 587 是默认端口;
- 如果您使用的是较旧的操作系统(Windows Server 2012/Windows 8 及更低版本),则必须使用以下命令为 PowerShell 启用 TLS 1.2 协议支持:
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
下表列出了可用于从 PowerShell 发送消息的常用公共电子邮件提供商的 SMTP 服务器设置(请注意,您必须在帐户界面中允许通过 SMTP 发送电子邮件。):
| 姓名 | SMTP 服务器地址 | 港口 | 加密类型 |
| 邮箱 | smtp.gmail.com | 第587章 25 第465章 |
传输层安全协议 传输层安全协议 SSL协议 |
| 微软(Office)365 | smtp.office365.com | 第587章 | 传输层安全协议 |
| Outlook.com | smtp-mail.outlook.com | 第587章 | 传输层安全协议 |
| 雅虎 | smtp.mail.yahoo.com | 第587章 | 传输层安全协议 |
| iCloud 邮件 | smtp.mail.me.com | 第587章 | 传输层安全协议 |
| 美国在线 | smtp.aol.com | 第465章 | SSL协议 |
如果 SMTP 服务器不允许匿名电子邮件(中继被拒绝),您将看到以下错误:
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 服务器进行身份验证-凭据选项。
您可以以交互方式提示用户输入身份验证凭据:
Send-MailMessage …… -Credential (Get-Credential)


您还可以在变量中指定用于身份验证的帐户凭据:
$cred = Get-Credential
Send-MailMessage ... -Credential $cred
如何使用 PowerShell 通过 Gmail SMTP 发送电子邮件?
要从您在公共邮件服务之一上的邮箱发送电子邮件,建议您使用应用程序密码而不是密码来访问您的帐户/邮箱。例如,在 Gmail 中,您可以在为 Google 帐户启用两步验证后创建应用程序密码。在 Google 上生成并复制您的应用密码(16 个字符的密码)。


以下示例演示如何使用 PowerShell 从 Google 邮箱发送电子邮件。您必须使用应用程序密码而不是 Google 帐户密码。在此示例中,我们将直接在 PowerShell 脚本代码中指定用于连接 Gmail SMTP 服务器的应用程序密码。
$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
参见:
请注意,PowerShell 会将命令和纯文本密码保存在 PowerShell 命令历史记录文件中。
在新版本的 PowerShell Core 7.x 中使用 Send-MailMessage 命令时,会显示警告:
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 cmdlet 使用不支持现代身份验证方法(包括 Microsoft 现代身份验证)的 .NET SmtpClient 类。建议您使用 Graph API 通过 Microsoft 365/Exchange Online 从 PowerShell 发送电子邮件(通过使用Send-MgUserMail小命令或Invoke-RestMethod通过 REST API 调用 sendMail 方法)。
