SQL Server代理执行PowerShell发送Office365邮件失败求助
问题描述
我需要通过SQL Server发送邮件:
- 本地机器上,使用Google账号的Windows PowerShell脚本可正常运行;
- 修改为Office365账号的脚本后,本地也能正常工作;
- 部署到办公机器后,Google账号脚本仍正常,但Office365账号脚本以
NT Service\SQLSERVERAGENT用户执行时,抛出错误:Executed as user: NT Service\SQLSERVERAGENT. Exception calling "Send" with "1" argument(s): "Failure sending mail."
排查方向与解决方法
1. 处理Office365的SMTP认证限制
Office365已逐步淘汰普通密码的SMTP客户端认证:
- 如果账号开启了多因素认证(MFA),必须使用应用密码替代普通登录密码;
- 未开启MFA的账号,需在Office365管理员后台确认该账号的
SMTP客户端授权权限已启用。
2. 解决NT Service\SQLSERVERAGENT账户的环境限制
该服务账户是本地系统账户,存在以下潜在问题:
- 防火墙/代理拦截:检查办公机器防火墙是否允许587端口出站连接到
smtp.office365.com;若使用代理,需在脚本中添加代理配置:# 添加代理配置(按需修改代理地址) $SMTPClient.Proxy = New-Object System.Net.WebProxy("http://your-proxy-server:port") $SMTPClient.Proxy.Credentials = [System.Net.CredentialCache]::DefaultNetworkCredentials - 账户权限不足:尝试将SQL Server Agent的运行账户切换为拥有Office365访问权限的域账户,测试邮件发送是否正常。
3. 补全脚本中的SMTP必要配置
Office365 SMTP要求明确禁用默认凭据,否则会自动使用执行账户的凭据导致认证失败,需在脚本中添加:
$SMTPClient.UseDefaultCredentials = $false # 必须添加此配置
4. 强制启用TLS 1.2
Office365要求SMTP连接使用TLS 1.2或更高版本,本地系统账户默认可能使用较低版本,需在脚本开头添加:
# 强制启用TLS 1.2 [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
完整脚本示例
Google账号脚本
$EmailTo = "xxxxxxx@gmail.com" $EmailFrom = "xxxxxxx@gmail.com" $Subject = "Test" $Body = "Test Body" $SMTPServer = "smtp.gmail.com" $SMTPMessage = New-Object System.Net.Mail.MailMessage($EmailFrom,$EmailTo,$Subject,$Body) $SMTPClient = New-Object Net.Mail.SmtpClient($SmtpServer, 587) $SMTPClient.EnableSsl = $true $SMTPClient.Credentials = New-Object System.Net.NetworkCredential("xxxxxxx@gmail.com", "MyPassword"); $SMTPClient.Send($SMTPMessage)
修改后的Office365账号脚本
# 强制启用TLS 1.2 [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 $EmailTo = "xxxxxxxxx@office.co.in" $EmailFrom = "xxxxxxxxx@office.co.in" $Subject = "Test" $Body = "Test Body" $SMTPServer = "smtp.office365.com" $SMTPMessage = New-Object System.Net.Mail.MailMessage($EmailFrom,$EmailTo,$Subject,$Body) $SMTPClient = New-Object Net.Mail.SmtpClient($SmtpServer, 587) $SMTPClient.EnableSsl = $true $SMTPClient.UseDefaultCredentials = $false # 新增配置 $SMTPClient.Credentials = New-Object System.Net.NetworkCredential("xxxxxxxxx@office.co.in", "YourAppPassword"); # 若需代理,添加以下配置 # $SMTPClient.Proxy = New-Object System.Net.WebProxy("http://your-proxy-server:port") # $SMTPClient.Proxy.Credentials = [System.Net.CredentialCache]::DefaultNetworkCredentials $SMTPClient.Send($SMTPMessage)
内容的提问来源于stack exchange,提问作者Jos Raj TimO
相关产品推荐
相关产品推荐

