You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PowerShell Send-MailMessage发送纯文本邮件特殊字符乱码求助

PowerShell纯文本邮件变音符号乱码修复方案

问题核心原因

你已经在参数中指定了Encoding = [System.Text.Encoding]::UTF8,但Send-MailMessage存在原生设计缺陷:发送纯文本邮件时,它不会自动在邮件MIME头中写入charset=utf-8的声明。绝大多数邮件客户端收到无明确字符集标识的纯文本邮件时,会默认使用ISO-8859-1或收件人系统本地默认编码解析正文,直接导致ä、ö、ü、ß这类变音符号显示乱码。
注意:业务要求纯文本格式不需要使用-BodyAsHtml参数,不要被网上通用的HTML邮件修复方案误导。

可直接落地的修复方法

方案1:最小改动修复(保留原有Send-MailMessage写法)

在原有发送参数的哈希表中,手动添加AdditionalHeaders项,强制声明纯文本正文的字符集为UTF-8,修复后的参数块如下:

$param = @{ 
    SmtpServer = $settings.mail.SmtpServer
    Port = $settings.mail.Port
    UseSsl = $true
    Credential = $userCredential
    From = $settings.mail.FromUser
    To = $settings.mail.ToUser
    Subject = $settings.mail.Subject
    Body = $plainTextBody
    Priority = 'High'
    DeliveryNotificationOption = 'OnFailure'
    ErrorAction = 'Stop'
    Encoding = [System.Text.Encoding]::UTF8
    # 新增以下行,手动声明MIME字符集和传输编码
    AdditionalHeaders = @{
        'Content-Type' = 'text/plain; charset=utf-8'
        'Content-Transfer-Encoding' = '8bit'
    }
}
Send-MailMessage @param

以上配置同时覆盖了主题、正文的特殊字符编码需求,不需要额外修改其他逻辑。

方案2:稳定兼容方案(替换过时的Send-MailMessage)

微软已经在PowerShell官方文档中标记Send-MailMessage为过时cmdlet,长期使用建议直接调用.NET底层类库发送邮件,完全可控编码逻辑,不会出现隐式转码问题,核心发送逻辑替换为以下代码即可:

# 初始化邮件消息对象,明确指定UTF-8编码
$mailMessage = [System.Net.Mail.MailMessage]::new(
    $settings.mail.FromUser,
    $settings.mail.ToUser,
    $settings.mail.Subject,
    $plainTextBody
)
$mailMessage.Priority = [System.Net.Mail.MailPriority]::High
$mailMessage.DeliveryNotificationOptions = [System.Net.Mail.DeliveryNotificationOptions]::OnFailure
# 明确指定正文为纯文本格式、UTF-8编码
$mailMessage.BodyEncoding = [System.Text.Encoding]::UTF8
$mailMessage.SubjectEncoding = [System.Text.Encoding]::UTF8
$mailMessage.IsBodyHtml = $false

# 初始化SMTP客户端发送
$smtpClient = [System.Net.Mail.SmtpClient]::new($settings.mail.SmtpServer, $settings.mail.Port)
$smtpClient.EnableSsl = $true
$smtpClient.Credentials = $userCredential
$smtpClient.Send($mailMessage)

# 释放资源
$mailMessage.Dispose()
$smtpClient.Dispose()

额外注意事项

  • 你定义的$plainTextBody多行字符串中每行开头的缩进空格会被原样带入邮件正文,如果不需要正文前的多余空白,把多行字符串的每行顶格书写即可。
  • 不要为了适配变音符号改用ISO-8859-1编码,UTF-8可以完整覆盖所有西欧变音符号,同时兼容多语言客户端环境。
  • 测试时不要用同一个邮件客户端反复收同主题邮件做验证,部分客户端会缓存旧邮件的编码配置,容易出现修复后仍显示乱码的误判。

内容的提问来源于stack exchange,提问作者Thomas Steso

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 23:01:40