Alerts and Notifications for SQL Server Login, Database User and Role Membership Changes

By:   |   Comments (18)   |   Related: 1 | 2 | 3 | 4 | > Security


Problem

SQL Server security monitoring is a critical part of the Database Administrator's job. Some security related alerts could be setup very easy, but others require third-party tools or extra steps to setup.  For example, SQL Server Audit can be used to monitor logins or users modification, but it requires audit log review. We would like to get real-time alerts every time a login or a user is created or added to a server or a database role, how can this be done?

Solution

In one of our previous tips, we explained how to setup WMI alerts for database changes monitoring. The setup consists of SQL Server Agent configuration steps, Database Mail configuration, and creation of the alert and a SQL Server Agent Job.

In this tip we will provide steps and scripts for setting up WMI alerts and jobs responding to these alerts to monitor the creation and removal of users and logins as well as server and database roles membership changes.

SQL Server AGent Jobs and alerts

Make sure that Database Mail is configured and SQL Server Agent is setup to allow replacing tokens as per this tip.

We will provide jobs steps and alerts screenshots and a complete script at the end of the tip for all of the jobs and alerts.

Note - The jobs are not scheduled and cannot be run manually.

Create SQL Server Alert for Create Login and Drop Login Events

In this section we will create a SQL Server Agent Job and an Alert for when logins are created or dropped.

Create SQL Server Job for Create Login and Drop Login Events

The following job ("WMI Response - Audit Add/Remove Login Event") will be responding to the WMI event every time a login is created or deleted.

To create a SQL Server Job, expand SQL Server Agent in SQL Server Management Studio and right click on Jobs and select New Job.

The image below displays the job's step. You will need to update @profile_name and @recipients parameters with your values (@profile_name will be the "Mail profile" that you created during Database Mail configuration):

Job that will Respond to the Login Creation/Deletion Events

Here is the script for the job step above (you will need to update @profile and @recipients parameters with your values):

DECLARE @p_subject NVARCHAR(255), @p_action INT 

SELECT @p_action = $(ESCAPE_SQUOTE(WMI(EventSubClass)))

SELECT  @p_subject = N'WMI Alert: Login [$(ESCAPE_SQUOTE(WMI(ObjectName)))] ' + 
      CASE WHEN  @p_action = 1 THEN 'created on' 
           WHEN  @p_action = 3 THEN 'dropped from' 
           ELSE 'changed on' 
      END + 
      ' [$(ESCAPE_SQUOTE(WMI(ComputerName)))\$(ESCAPE_SQUOTE(WMI(SQLInstance)))].' ;

EXEC msdb.dbo.sp_send_dbmail
   @profile_name = 'DBServerAlerts', -- update with your values
   @recipients = '[email protected]', -- update with your values
   @subject = @p_subject,
   @body = N'Time: $(ESCAPE_SQUOTE(WMI(StartTime))); 
ComputerName: $(ESCAPE_SQUOTE(WMI(ComputerName)));
SQL Instance: $(ESCAPE_SQUOTE(WMI(SQLInstance))); 
Database: $(ESCAPE_SQUOTE(WMI(DatabaseName)));
Target Login Name: $(ESCAPE_SQUOTE(WMI(ObjectName)));
Source Application Name: $(ESCAPE_SQUOTE(WMI(ApplicationName)));
Source Host Name: $(ESCAPE_SQUOTE(WMI(HostName)));
Source Login Name: $(ESCAPE_SQUOTE(WMI(LoginName)));
Source Session Login Name: $(ESCAPE_SQUOTE(WMI(SessionLoginName)));
EventSubClass: $(ESCAPE_SQUOTE(WMI(EventSubClass)));
';
GO	

Create WMI Event for Create Login and Drop Login Events

To create a SQL Server Alert, expand SQL Server Agent in SQL Server Management Studio and right click on Alerts and select New Alert.

Now we will setup the WMI alert:

  • Set the alert type to "WMI event alert"
  • Make sure you use the correct WMI namespace:
WMI Alert to Respond to the Login Creation/Deletion Events

Note: The namespace will be different for the default instance and for the named instance. Here are some examples.

-- DEFAULT instance's namespace ("DEMOSQL1" SQL Server):
\\.\root\Microsoft\SqlServer\ServerEvents\MSSQLSERVER
 
--NAMED instance's namespace ("DEMOSQL1\SQLINSTANCE1" SQL Server):
\\.\root\Microsoft\SqlServer\ServerEvents\SQLINSTANCE1			

Here is the WMI query for this alert:

select * from AUDIT_SERVER_PRINCIPAL_MANAGEMENT_EVENT where EventSubClass= 1 or EventSubClass = 3

Set the response in the alert's properties to execute the SQL Server job we created earlier:

Alert to Respond to the Login Creation/Deletion Events - response

Create SQL Server Alert for Add Member and Drop Member Server Role Events

In this section we will create a SQL Server Agent Job and an Alert for when logins are added or dropped from SQL Server server roles.

Create SQL Server Job for Add Member and Drop Member Server Role Events

Here is the "WMI Response - Audit Add/Remove Server Role Member Event " job's step for the server roles membership changes monitoring response:

Job that will Respond to the Server Roles Add/Remove Logins Events

Here is the script for the job step:

DECLARE @p_subject NVARCHAR(255), @p_action INT 

SELECT @p_action = $(ESCAPE_SQUOTE(WMI(EventSubClass)))

SELECT @p_subject = N'WMI Alert: Login [$(ESCAPE_SQUOTE(WMI(TargetLoginName)))] ' + 
      CASE WHEN  @p_action = 1 THEN 'added to the' 
           WHEN @p_action = 2 THEN 'removed from the' 
           ELSE 'changed on' 
      END + 
      ' [$(ESCAPE_SQUOTE(WMI(RoleName)))] Server Role on [$(ESCAPE_SQUOTE(WMI(ComputerName)))\$(ESCAPE_SQUOTE(WMI(SQLInstance)))].' ;

EXEC msdb.dbo.sp_send_dbmail
   @profile_name = 'DBServerAlerts', -- update with your values
   @recipients = '[email protected]', -- update with your values
   @subject = @p_subject,
   @body = N'Time: $(ESCAPE_SQUOTE(WMI(StartTime))); 
Computer Name: $(ESCAPE_SQUOTE(WMI(ComputerName)));
SQL Instance: $(ESCAPE_SQUOTE(WMI(SQLInstance))); 
Database: $(ESCAPE_SQUOTE(WMI(DatabaseName)));
Target Login Name: $(ESCAPE_SQUOTE(WMI(TargetLoginName)));
Target Server Role Name: $(ESCAPE_SQUOTE(WMI(RoleName)));
Source Application Name: $(ESCAPE_SQUOTE(WMI(ApplicationName)));
Source Host Name: $(ESCAPE_SQUOTE(WMI(HostName)));
Source Login Name: $(ESCAPE_SQUOTE(WMI(LoginName)));
Source Session Login Name: $(ESCAPE_SQUOTE(WMI(SessionLoginName)));
SQL Statement: $(ESCAPE_SQUOTE(WMI(TextData)));
EventSubClass: $(ESCAPE_SQUOTE(WMI(EventSubClass)));
';	

Create WMI Event for Add Member and Drop Member Server Role Events

Now we will create the WMI alert as following:

Alert to Respond to the Server Roles Add/Remove Logins Events

Here is the WMI query for this alert:

select * from AUDIT_ADD_LOGIN_TO_SERVER_ROLE_EVENT			

If you want to audit only "sysadmin" role membership changes you can update the alert's WMI query above with this:

select * from AUDIT_ADD_LOGIN_TO_SERVER_ROLE_EVENT where RoleName='sysadmin'			

Set the response in the alert's properties to execute the job we created earlier:

Alert to Respond to the Server Roles Add/Remove Logins Events - response

Create SQL Server Alert for Create User and Drop User Events

In this section we will create a SQL Server Agent Job and an Alert for when users are created or dropped for a database. 

Create SQL Server Job for Create User and Drop User Events

This job ("WMI Response - Audit Add/Remove Database User Event") will respond to the alerts triggered when a user in a database is created or if a user is deleted from the database:

Job that will Respond to the User Creation/Deletion Events

Here is the script for the job step:

DECLARE @p_subject NVARCHAR(255), @p_action INT 

SELECT @p_action = $(ESCAPE_SQUOTE(WMI(EventSubClass)))

SELECT  @p_subject = N'WMI Alert: Database User [$(ESCAPE_SQUOTE(WMI(TargetUserName)))] ' + 
      CASE WHEN  @p_action = 3 THEN 'added to' 
           WHEN @p_action = 4 THEN 'removed from' 
           WHEN @p_action = 1 THEN 'added to the [$(ESCAPE_SQUOTE(WMI(RoleName)))] Database Role on'  
           WHEN @p_action = 2 THEN 'removed from the [$(ESCAPE_SQUOTE(WMI(RoleName)))] Database Role on' 
           ELSE 'changed on' 
      END + 
      ' [$(ESCAPE_SQUOTE(WMI(ComputerName)))\$(ESCAPE_SQUOTE(WMI(SQLInstance)))]:[$(ESCAPE_SQUOTE(WMI(DatabaseName)))].' ;

EXEC msdb.dbo.sp_send_dbmail
   @profile_name = 'DBServerAlerts', -- update with your values
   @recipients = '[email protected]', -- update with your values
   @subject = @p_subject,
   @body = N'Time: $(ESCAPE_SQUOTE(WMI(StartTime))); 
Computer Name: $(ESCAPE_SQUOTE(WMI(ComputerName)));
SQL Instance: $(ESCAPE_SQUOTE(WMI(SQLInstance))); 
Database: $(ESCAPE_SQUOTE(WMI(DatabaseName)));
Target Login Name: $(ESCAPE_SQUOTE(WMI(TargetLoginName)));
Target DB User Name: $(ESCAPE_SQUOTE(WMI(TargetUserName)));
Source Application Name: $(ESCAPE_SQUOTE(WMI(ApplicationName)));
Source Host Name: $(ESCAPE_SQUOTE(WMI(HostName)));
Source Login Name: $(ESCAPE_SQUOTE(WMI(LoginName)));
Source Session Login Name: $(ESCAPE_SQUOTE(WMI(SessionLoginName)));
EventSubClass: $(ESCAPE_SQUOTE(WMI(EventSubClass)));
';	

Create WMI Event Job for Create User and Drop User Events

Here is the WMI alert for the database users creation or deletion:

WMI Alert to Respond to the User Creation/Deletion Events

Here is the WMI query for this alert:

select * from AUDIT_ADD_DB_USER_EVENT			

Set the response in the alert's properties to execute the job we created earlier:

Alert to Respond to the User Creation/Deletion Events - response

Create SQL Server Alert for Add Member and Drop Member Database Role Events

In this section we will create a SQL Server job and an Alert for when users are added or dropped from database roles.

Create SQL Server Job for Add Member and Drop Member Database Role Events

This job ("WMI Response - Audit Add/Remove DB Role Member Event") will respond to the database roles membership modification events:

Job that will Respond to the Database Roles Add/Remove User Events

Here is the script for the job step:

DECLARE @p_subject NVARCHAR(500), @p_action INT 

SELECT @p_action = $(ESCAPE_SQUOTE(WMI(EventSubClass)))

SELECT  @p_subject = N'WMI Alert: User [$(ESCAPE_SQUOTE(WMI(TargetLoginName)))] ' + 
      CASE WHEN  @p_action = 1 THEN 'added to the' 
           WHEN @p_action = 2 THEN 'removed from the' 
           ELSE 'changed on' 
      END + 
      ' [$(ESCAPE_SQUOTE(WMI(RoleName)))] Database Role on [$(ESCAPE_SQUOTE(WMI(DatabaseName)))]:[$(ESCAPE_SQUOTE(WMI(ComputerName)))\$(ESCAPE_SQUOTE(WMI(SQLInstance)))].' ;

EXEC msdb.dbo.sp_send_dbmail
   @profile_name = 'DBServerAlerts', -- update with your values
   @recipients = '[email protected]', -- update with your values
   @subject = @p_subject,
   @body = N'Time: $(ESCAPE_SQUOTE(WMI(StartTime))); 
Computer Name: $(ESCAPE_SQUOTE(WMI(ComputerName)));
SQL Instance: $(ESCAPE_SQUOTE(WMI(SQLInstance))); 
Database: $(ESCAPE_SQUOTE(WMI(DatabaseName)));
Target User Name: $(ESCAPE_SQUOTE(WMI(TargetUserName)));
Target Database Role Name: $(ESCAPE_SQUOTE(WMI(RoleName)));
Source Application Name: $(ESCAPE_SQUOTE(WMI(ApplicationName)));
Source Host Name: $(ESCAPE_SQUOTE(WMI(HostName)));
Source Login Name: $(ESCAPE_SQUOTE(WMI(LoginName)));
Source Session Login Name: $(ESCAPE_SQUOTE(WMI(SessionLoginName)));
EventSubClass: $(ESCAPE_SQUOTE(WMI(EventSubClass)));	
	

Create WMI Event for Add Member and Drop Member Database Role Events

WMI alert for the database roles membership changes:

WMI Alert to Respond to the Database Roles Add/Remove User Events

Here is the WMI query for this alert:

select * from AUDIT_ADD_MEMBER_TO_DB_ROLE_EVENT			

Set the response in the alert's properties to execute the job we created earlier:

Alert to Respond to the Database Roles Add/Remove User Events - response

Testing SQL Server Security Alerts

Now we should be able to receive email notifications every time somebody creates or deletes logins or database users or adds or removes them from server or database roles.

Let's create a test login:

USE [master]
GO
CREATE LOGIN [_demo_user] 
   WITH PASSWORD=N'AlwaysStr0ngP@ssword', 
   DEFAULT_DATABASE=[master], 
   CHECK_EXPIRATION=ON, 
   CHECK_POLICY=ON
GO	

You should get an email as the following one:

Login created email

Now we will add this login to a server role:

USE [master]
GO
ALTER SERVER ROLE [bulkadmin] ADD MEMBER [_demo_user]
GO			

Here is an email notification:

Login added to the server role email

We will add this login as a database user on the Contoso database:

USE [Contoso]
GO
CREATE USER [_demo_user] FOR LOGIN [_demo_user]
GO			

Here is the email:

User created email

Now, we will add this user to the db_datareader database role:

USE [Contoso]
GO
ALTER ROLE [db_datareader] ADD MEMBER [_demo_user]
GO			

The email looks like this:

User added to the database role email

Removing a user from a database role:

USE [Contoso]
GO
ALTER ROLE [db_datareader] DROP MEMBER [_demo_user]
GO			

Here is an email example:

User removed from the database role email

Let's remove the user from the database:

USE [Contoso]
GO
DROP USER [_demo_user]
GO			

Here is the email:

User deleted email

Now, let's remove the login from the server role:

USE [master]
GO
ALTER SERVER ROLE [bulkadmin] DROP MEMBER [_demo_user]
GO			

Here is the email:

Login removed from the server role email

And, finally, delete the login completely from the SQL Server:

USE [master]
GO
DROP LOGIN [_demo_user]
GO			

Here is the email:

Login deleted email

Complete Script

The script for all of the jobs and alerts can be downloaded here.

Please note, that you may need to update the following parts of the script:

  • @wmi_namespace for the alerts (see the examples above)
  • @profile_name and @recipients parameters with your values (@profile_name will be the "Mail profile" that you created during Database Mail configuration)
  • Replace the job owner in the script if the "sa" login is renamed on your SQL Server:
@owner_login_name=N'sa'			
Next Steps


sql server categories

sql server webinars

subscribe to mssqltips

sql server tutorials

sql server white papers

next tip



About the author
MSSQLTips author Svetlana Golovko Svetlana Golovko is a DBA with 13 years of the IT experience (including SQL Server and Oracle) with main focus on performance.

This author pledges the content of this article is based on professional experience and not AI generated.

View all my tips



Comments For This Article




Thursday, March 2, 2023 - 12:58:38 PM - Charles Back To Top (90973)
Thank you for this excellent post and information. We implemented this successfully within our environment a few months ago without issue. However, we are not moving toward utilizing a central management server to host the jobs for all of our instances. We have discovered that when triggered, the hostname, username, etc do not correctly report within the alert email. I would assume this is because the t-sql is hosted on one server and run on another. Has anyone else run into this and have any workaround or tsql modifications been able to resolve this?

Thank you.

Charles

Friday, December 2, 2022 - 1:29:57 AM - DBA Back To Top (90745)
I'm getting the below error, Can someone help me here?

Msg 102, Level 15, State 1, Line 3
Incorrect syntax near 'ESCAPE_SQUOTE'.

Completion time: 2022-12-02T14:28:33.2040685+08:00

Thursday, September 15, 2022 - 10:24:43 PM - ganesh Back To Top (90488)
I followed all the steps and its working for all except for
USE --
GO
ALTER ROLE [--] ADD MEMBER [--]
GO

Receiving email

CAUTION: This email is from an external source. '--' Please beware of links and attachments.

DATE/TIME: 9/15/2022 10:21:59 PM

DESCRIPTION: (None)

COMMENT: (None)

JOB RUN: Audit Add/Remove DB Role Member Event


Please help

Sunday, May 22, 2022 - 4:29:52 AM - Ajay Mane Back To Top (90101)
Thanks for the post it is very helpful.

Thursday, February 27, 2020 - 3:40:51 PM - Svetlana Golovko Back To Top (84824)

Hi all,

I am replying to all issues that are listed in the comments.

I tested the scripts again and they work. A single quote is still missing on the script to add DB role member, but if you add it it should work.

The common reasons for the WMI alerts related errors are:

- database mail doesn't work

- tokens replacement in SQL Agent properties is not enabled

- job executed manually (it only supposed to work when triggered by the alert)

- the WMI namespace setup incorrectly in the WMI alert (it will be different for the default instance and for the named instance).


Monday, February 24, 2020 - 7:41:40 PM - Kar Back To Top (84778)

I am getting the below error when job executes from the alert?

Unable to start execution of step 1 (reason: Variable WMI(EventSubClass) not found).  The step failed.


Wednesday, November 20, 2019 - 9:48:26 AM - Terry Brothers Back To Top (83145)

Hi Svetlana,

Thank you very much for the scripting above. It's Exactly what I need.

However, there's an error on line 2 that I just cannot figure out.  SSMS says "Incorrect synrax near 'EventSubClass'.  Is there any way you can help me resolve the error?  It would be Greatly appreciated!

DECLARE @p_subject NVARCHAR(255), @p_action INT 

SELECT @p_action = $(ESCAPE_SQUOTE(WMI(EventSubClass)))

SELECT  @p_subject = N'WMI Alert: Login [$(ESCAPE_SQUOTE(WMI(TargetLoginName)))] '  + 

CASE WHEN  @p_action = 1 THEN 'added to the' 

WHEN + @p_action = 2 THEN 'removed from the' 

ELSE 'changed on' END + 

' [$(ESCAPE_SQUOTE(WMI(RoleName)))] Server Role on [$(ESCAPE_SQUOTE(WMI(ComputerName)))\$(ESCAPE_SQUOTE(WMI(MSSQLSERVER)))].' ;

Regards,

Terry Brothers


Monday, October 14, 2019 - 3:49:50 PM - Svetlana Back To Top (82775)

Hi all,

This tip had two updates:

- there was a missing closing single quote in one of the scripts (DB role member change job's step)

- the subject variable changed to fit one line for the Server Roles changes job's script. It was in two lines (for better readability), this caused the mail server to reject the email with an "incorrect subject format" message. 


Sunday, October 13, 2019 - 3:38:41 PM - Svetlana Golovko Back To Top (82759)

Hello,

Thanks for reading and trying it.

It looks like in the tip itself a single quote is missing for the DB role member change event (job step script).

As per the Server Roles changes try to set subject line in the job step to one line. SO, instead of this:

END + 
      ' [$(ESCAPE_SQUOTE(WMI(RoleName)))] Server Role 
        on [$(ESCAPE_SQUOTE(WMI(ComputerName)))\$(ESCAPE_SQUOTE(WMI(SQLInstance)))].' ;

use this
     END + 
      ' [$(ESCAPE_SQUOTE(WMI(RoleName)))] Server Role on [$(ESCAPE_SQUOTE(WMI(ComputerName)))\$(ESCAPE_SQUOTE(WMI(SQLInstance)))].' ;

Wednesday, October 2, 2019 - 2:46:07 PM - Megna Back To Top (82651)

Thanks for the post it is very helpful.

I am getting emails from 2 Events but i am not getting Emails from other 2 Events.

1. WMI Response - Audit Add/Remove Server Role Member Event

2. WMI Response - Audit Add/Remove DB Role Member Event

event Alert is Starting the Job and seems like the Job is Successful but its not sending an Email, I am confused. Can you Please help me to figure out.


Tuesday, September 24, 2019 - 5:24:17 AM - Andrew Robinson Back To Top (82552)

Nice article, thanks. I am no SQL expert so hope these comments make sense. It would be useful to have a more obvious indication that you actually have to set up auditing and what one would need to specify in the Server Audit Specification properties to capture these events. Also I found it confusing that the 'send email repsonse' Job step script was repeated for each alert.


Monday, July 8, 2019 - 1:36:01 PM - Karlos Back To Top (81709)

Svetana

yes i have set my alert to execute the job. I pretty much copied all the steps the only changes i have done was updating @profile and @recipients parameters to my values


Thursday, June 27, 2019 - 8:55:58 AM - Svetlana Back To Top (81607)

Hi Karlos

Have you set alert's response (execute a job on alert)?

Thanks,

Svetlana


Tuesday, June 25, 2019 - 3:22:24 PM - Karlos Back To Top (81583)

I was able to create the alerts and jobs but when receiving the email notification not getting any detaile like the examples 

Here is an example of the email notification i am receiving 

DATE/TIME: 6/25/2019 2:46:54 PM

DESCRIPTION: (None)

COMMENT: (None)

JOB RUN: (None)


Monday, April 15, 2019 - 1:31:05 PM - Svetlana Back To Top (79564)

Hi Lynn,

Check if the "Token Replacement" setting is set for SQL Server Agent.

This tip has the steps for the SQL Server Agent configuration: https://www.mssqltips.com/sqlservertip/3095/monitor-sql-server-databases-changes-using-wmi-alerts/

Thanks,

Svetlana


Wednesday, April 10, 2019 - 3:58:22 PM - Lynn Tims Back To Top (79521)

 I am getting the below error when job executes from the alert?

Unable to start execution of step 1 (reason: Variable WMI(EventSubClass) not found).  The step failed.


Wednesday, February 20, 2019 - 1:16:16 PM - Svetlana Golovko Back To Top (79071)

Hi Ananda,

Please check a previous tip here https://www.mssqltips.com/sqlservertip/3095/monitor-sql-server-databases-changes-using-wmi-alerts/ for the explanation. Search the previous tip for "22022" . It looks that you use non-default instance and setup your WMI alert incorrectly. It should be in format: \\.\root\Microsoft\SqlServer\ServerEvents\INSTANCE1 (where the "INSTANCE1" is your instance name).

Thanks for reading,

Svetlana


Tuesday, February 19, 2019 - 4:56:41 AM - Ananda Back To Top (79059)

Thanks for sharing this login aduit script , but recevied error while executing downloaded full script. SQL 2012 version

 Msg 22022, Level 16, State 1, Line 57

SQLServerAgent Error: WMI error: 0x8004100e.

Msg 14511, Level 16, State 1, Procedure sp_verify_alert, Line 304 [Batch Start Line 57]

The @wmi_query could not be executed in the @wmi_namespace provided. Verify that an event class selected in the query exists in the namespace and that the query has the correct syntax.

Msg 22022, Level 16, State 1, Line 165

SQLServerAgent Error: WMI error: 0x8004100e.

Msg 14511, Level 16, State 1, Procedure sp_verify_alert, Line 304 [Batch Start Line 165]

The @wmi_query could not be executed in the @wmi_namespace provided. Verify that an event class selected in the query exists in the namespace and that the query has the correct syntax.

Msg 22022, Level 16, State 1, Line 218

SQLServerAgent Error: WMI error: 0x8004100e.

Msg 14511, Level 16, State 1, Procedure sp_verify_alert, Line 304 [Batch Start Line 218]

The @wmi_query could not be executed in the @wmi_namespace provided. Verify that an event class selected in the query exists in the namespace and that the query has the correct syntax.















get free sql tips
agree to terms