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

无需凭据通过Outlook发送SSIS包失败通知邮件的方法

SSIS包执行失败邮件通知问题解决

一、解决Office365 SMTP连接错误(net_io_connection closed)

出现这个错误核心是Office365的SMTP验证机制与旧版工具的兼容性问题,按以下步骤排查修复:

  • 检查MFA与应用密码:如果你的Office365账号开启了多因素认证(MFA),普通密码无法用于SMTP验证,必须登录微软账户后台生成应用密码,替换代码中的明文密码。
  • 替换为支持现代验证的邮件库:.NET Framework自带的SmtpClient已被标记为过时,对Office365的现代验证支持不佳,建议改用MailKit库:
    1. 给脚本任务添加MailKit和MimeKit的引用(先通过NuGet安装,再将DLL复制到脚本任务的引用目录)
    2. 修改后的核心代码示例:
      using MailKit.Net.Smtp;
      using MimeKit;
      
      // 读取变量代码不变
      String SendMailFrom = Dts.Variables["EmailFrom"].Value.ToString();
      String SendMailTo = Dts.Variables["EmailTo"].Value.ToString();
      String SendMailSubject = Dts.Variables["EmailSubject"].Value.ToString();
      String SendMailBody = Dts.Variables["EmailBody"].Value.ToString();
      
      try
      {
          var email = new MimeMessage();
          email.From.Add(new MailboxAddress("", SendMailFrom));
          email.To.Add(new MailboxAddress("", SendMailTo));
          email.Subject = SendMailSubject;
          email.Body = new TextPart("plain") { Text = SendMailBody };
      
          using (var client = new SmtpClient())
          {
              client.Connect("smtp.office365.com", 587, MailKit.Security.SecureSocketOptions.StartTls);
              // MFA账号用应用密码,非MFA用普通密码(从变量读取)
              client.Authenticate(SendMailFrom, Dts.Variables["EmailPassword"].Value.ToString());
              client.Send(email);
              client.Disconnect(true);
          }
      }
      catch (Exception ex)
      {
          // 不要用MessageBox,后台运行时无法显示,改为写入SSIS日志
          Dts.Events.FireError(0, "Script Task", ex.ToString(), "", 0);
      }
      Dts.TaskResult = (int)ScriptResults.Success;
      
  • 排查网络限制:确认运行SSIS的服务器能访问smtp.office365.com的587端口,没有被防火墙、代理拦截。

二、避免硬编码凭据,安全发送邮件的方案

方案1:使用SSIS内置「发送邮件任务」+ Database Mail(最推荐)

这是SSIS官方推荐的方式,无需手写脚本,安全且稳定:

  • 先在SQL Server中配置Database Mail:添加SMTP账户,填入Office365的SMTP信息,凭据会被加密存储在Database Mail中。
  • 在SSIS包中添加「发送邮件任务」,选择已配置的Database Mail账户,设置收件人、主题、正文即可。SQL Agent运行时使用代理账户权限,不会暴露任何明文凭据。

方案2:脚本任务中安全存储凭据

如果必须用脚本任务,绝对不能硬编码密码:

  • 将密码存入SSIS环境变量或配置文件,通过Dts.Variables读取。
  • 同时将包的保护级别设置为EncryptSensitiveWithUserKey(仅当前用户可解密)或EncryptSensitiveWithPassword(用密码加密敏感信息),防止变量泄露。
  • 代码示例:
    // 从包变量读取密码,而非硬编码
    SmtpServer.Credentials = new System.Net.NetworkCredential(SendMailFrom, Dts.Variables["EmailPassword"].Value.ToString());
    

方案3:无密码的现代验证(企业级场景)

针对Office365,可通过Azure AD应用注册实现无密码验证:

  • 在Azure AD中注册应用,获取租户ID、客户端ID、客户端密钥。
  • 用MailKit结合Microsoft身份验证库(MSAL)获取访问令牌,再进行SMTP验证。核心代码片段:
    using Microsoft.Identity.Client;
    using MailKit.Net.Smtp;
    using MimeKit;
    
    // 获取OAuth2令牌
    var app = ConfidentialClientApplicationBuilder
        .Create("你的客户端ID")
        .WithTenantId("你的租户ID")
        .WithClientSecret("你的客户端密钥")
        .Build();
    var scopes = new[] { "https://outlook.office365.com/SMTP.Send" };
    var result = await app.AcquireTokenForClient(scopes).ExecuteAsync();
    
    // 发送邮件
    var email = new MimeMessage();
    email.From.Add(new MailboxAddress("", SendMailFrom));
    email.To.Add(new MailboxAddress("", SendMailTo));
    email.Subject = SendMailSubject;
    email.Body = new TextPart("plain") { Text = SendMailBody };
    
    using (var client = new SmtpClient())
    {
        client.Connect("smtp.office365.com", 587, SecureSocketOptions.StartTls);
        client.Authenticate(new SaslMechanismOAuth2(SendMailFrom, result.AccessToken));
        client.Send(email);
        client.Disconnect(true);
    }
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 06:12:09