sql-serverpowershellemailtriggersdatabase-mail

Calling Powershell script from SQL Server trigger


Is it possible to use powershell "Send-MailMessage -SMTPServer" command from the sql server trigger?

I am trying to send emails when the rows in database update or new row created. I am not able to use Database-mail due to security restrictions. However, I can send emails through powershell's Send-MailMessage command.


Solution

  • First off, this is almost certainly a very bad idea. Keep in mind that triggers can cause unexpected issues in terms of transaction escalation and holding locks longer than necessary while they're processing. Also keep in mind that people will probably not expect there to be triggers of this sort on your table, and that they'll try to do CRUD operations on it like it's a normal table and not understand why their applications are timing out.

    That said, you could do this at least three ways:

    1. Enable xp_cmdshell, and use that to shell out to PowerShell, as explained here: Running Powershell scripts through SQL - but don't do this, because xp_cmdshell is a security risk and this is very likely to cause problems for you in one way or another (whether because someone uses it in a damaging manner or because PowerShell just fails and you don't even know why). If you can't use database mail due to security restrictions, you should definitely not be using xp_cmdshell, which has even more security concerns!
    2. Instead of using PowerShell, configure Database Mail have your trigger call sp_db_sendmail - but don't do this because this could easily fail or cause problems for your updates (e.g. SMTP server goes down and your table can't be updated anymore). (I wrote this part before I saw you can't use it because of security restrictions.)
    3. One other option comes to mind that may be more secure, but still not ideal - create a SQL CLR library that actually sends the mail using the .NET SmptClient. This could be loaded into your instance and exposed as a regular SQL function that could be called from your trigger. This can be done more securely than just enabling xp_cmdshell, but if you don't have the ability to configure Database mail this probably violates the same policy.

    Instead of these options, I'd recommend something like these:

    1. Instead of sending an email every time there's an update, have your trigger write to a table (or perhaps to a Service Broker Queue); create a job to send emails periodically with the latest data from that table, or create some kind of report off of that. This would be preferable because writing to a table or SSB queue should be faster and less prone to error than trying to send an email from in a trigger.
    2. Configure and use Change Data Capture. You could even write some agent jobs or something to regularly email users when there are updates. If your version supports this, it may be a bit more powerful and configurable for you, and solve some problems that triggers can cause more easily.