从 SQL 服务器触发器调用 Powershell 脚本

Calling Powershell script from SQL Server trigger

是否可以从 sql 服务器触发器使用 powershell "Send-MailMessage -SMTPServer" 命令?

我正在尝试在数据库中的行更新或创建新行时发送电子邮件。由于安全限制,我无法使用数据库邮件。但是,我可以通过 powershell 的 Send-MailMessage 命令发送电子邮件。

首先,这几乎可以肯定是一个非常糟糕的主意。请记住,触发器可能会在事务升级和处理过程中持有锁的时间超过必要时间方面导致意外问题。还要记住,人们可能不会期望在您的 table 上有这种类型的触发器,并且他们会尝试对其进行 CRUD 操作,就像它是正常的 table 并且不明白为什么他们的应用程序超时。

也就是说,您至少可以通过三种方式做到这一点:

  1. 启用 xp_cmdshell,并将其用于 shell 到 PowerShell,如此处解释:Running Powershell scripts through SQL - 但不要这样做,因为 xp_cmdshell 是一个安全风险,这很可能以某种方式给您带来问题(无论是因为有人以破坏性的方式使用它,还是因为 PowerShell 只是失败而您甚至不知道为什么)。 如果你因为安全限制不能使用数据库邮件,你绝对不应该使用xp_cmdshell,这更具有安全隐患!
  2. 不要使用 PowerShell,而是配置 Database Mail have your trigger call sp_db_sendmail - 但不要这样做,因为这很容易失败或导致您的更新出现问题(例如 SMTP 服务器出现故障而您的 table 不能再更新)。 (这部分是我写的,之前看到你因为安全限制不能用
  3. 想到另一个可能更安全但仍不理想的选择 - 创建一个 SQL CLR 库,它实际上使用 .NET SmptClient 发送邮件。这可以加载到您的实例中,并作为可以从触发器调用的常规 SQL 函数公开。这比仅启用 xp_cmdshell 更安全,但如果您无法配置数据库邮件,这可能违反了相同的策略。

除了这些选项,我还推荐以下选项:

  1. 不是每次有更新时都发送电子邮件,而是让您的触发器写入 table(或者可能写入 Service Broker 队列);创建一个作业,定期发送包含来自 table 的最新数据的电子邮件,或者创建某种报告。这将是更可取的,因为写入 table 或 SSB 队列应该比尝试从触发器中发送电子邮件更快且更不容易出错。
  2. 配置和使用Change Data Capture。您甚至可以编写一些代理作业或其他内容,以便在有更新时定期向用户发送电子邮件。如果你的版本支持这个,它可能会更强大,更容易配置,更容易解决一些触发器可能导致的问题。