By: Svetlana Golovko || Related Tips:More >Monitoring
ProblemSQL Server Audit can be used to monitor numerous security events, but it requires audit logs review which could be time consuming. We would like to get real-time alerts every time when Server Scope Permissions or Server Objects Permissions are changed. How do we setup alerts and jobs responding to these alerts?
SolutionIn one of our previoustips, we explained how to setup WMI alerts for database changes monitoring. The setup consists ofSQL Server Agent configuration steps,Database Mail configuration, and creation of the alert and SQL Server job.
In this tip we will provide steps and scripts for setting up WMI alerts to monitor the Server Scope or Server Objects Permissions changes and jobs responding to these alerts. Here are some of the examples of these permissions:
Login granted "CONTROL SERVER" Login granted SQL Server Access ("CONNECT SQL") "CREATE ANY DATABASE" permission granted "VIEW ANY DEFINITION" permission granted Login granted permissions to alter another login Login granted permissions to alter server role (permission can be granted only to acustom Server Role)A "Server" Type Securable permission is available by to any login who has access to SQL Server. This is when a login has "CONNECT SQL" permission. The login could be granted additional Server Scope permissions (for example, "ALTER ANY DATABASE"):

The same permissions are accessible through the "Server Properties" in SQL Server Management Studio (SSMS):

There are other Securables (Object Types) available in addition to the "Server". We can see available Object Types by clicking "Search..." button in SQL Server Management Studio (SSMS) when we open a login's property (the "Securables" page):

Here is the list of available Objects Types through the SSMS on our test SQL Server:

Note:If Availability Groups are not configured on SQL Server then the "Availability Groups" Object Type won't be available.
Setting permissions on the "Server" Object Type triggers alerts (if they were setup) using AUDIT_SERVER_SCOPE_GDR_EVENT WMI Class. The rest of the Object Types permissions use AUDIT_SERVER_OBJECT_GDR_EVENT WMI Class.
An example of the "Server" type Securable permission is already covered in theprevious tip when we provided the steps to monitor login's permission to access SQL Server.
In this tip we will provide more examples to monitor the "Server" type Securable permissions and steps and scripts to get alerts on Server Objects Permissions changes.
Here are the jobs and alerts that will be created:

Make sure that the Database Mail is configured and SQL Server Agent is setup to allow replacing tokens as per thistip.
We will provide the jobs' steps and alerts screenshots and a complete script at the end of the tip for all of the jobs and alerts.
Note, that the jobs are not scheduled and cannot be run manually or on schedule.
Create SQL Server Agent Job that will Respond to the Server Scope Permissions ChangesThe following job ("WMI Response - Audit Server Scope GDR Event") will be responding to the WMI event every time when a Server Scope Permission is granted/denied/revoked to/from a login.
Here is the documentation about granting the Server Permissions.
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):

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, @p_importance VARCHAR (6) ,@p_action_desc NVARCHAR(10), @p_permission NVARCHAR(255), @TextData NVARCHAR(500)
SELECT @p_action = $(ESCAPE_SQUOTE(WMI(EventSubClass))),
@p_importance = CASE WHEN $(ESCAPE_SQUOTE(WMI(Success))) = 0 THEN 'High' ELSE 'Normal' END,
@p_action_desc = CASE WHEN @p_action = 1 THEN 'GRANT'
WHEN @p_action = 3 THEN 'DENY'
WHEN @p_action = 2 THEN 'REVOKE' END,
@TextData = LTRIM(RTRIM(REPLACE('$(ESCAPE_SQUOTE(WMI(TextData)))', char(9), ' ')))
SELECT @p_permission =
LTRIM(RTRIM(SUBSTRING(@TextData,
CHARINDEX(@p_action_desc, @TextData, 0)+ LEN(@p_action_desc),
CHARINDEX(CASE WHEN @p_action = 2 THEN ' FROM ' ELSE ' TO ' END,
@TextData, 0) - CHARINDEX(@p_action_desc, @TextData, 0) - LEN(@p_action_desc)) ))
SELECT @p_subject = N'WMI Alert: Login [$(ESCAPE_SQUOTE(WMI(TargetLoginName)))] ' +
' - [' + @p_permission + '] ' +
' SQL Server Permission ' + CASE WHEN @p_action = 1 THEN 'granted'
WHEN @p_action = 2 THEN 'revoked'
WHEN @p_action = 3 THEN 'denied'
ELSE '' END + ' on [$(ESCAPE_SQUOTE(WMI(ComputerName)))\$(ESCAPE_SQUOTE(WMI(SQLInstance)))].' ;
EXEC msdb.dbo.sp_send_dbmail
@profile_name = 'DBServerAlerts', -- update with your values
@recipients = '<a href="/cdn-cgi/l/email-protection" data-cfemail="9ffbfdfec0faf2fef6f3dfe6f0eaeddcf0edefdbf0f2fef6f1b1fcf0f2">[email protected]</a>', -- update with your values
@importance = @p_importance ,
@subject = @p_subject,
@body = N'Time: $(ESCAPE_SQUOTE(WMI(StartTime)));
ComputerName: $(ESCAPE_SQUOTE(WMI(ComputerName)));
SQL Instance: $(ESCAPE_SQUOTE(WMI(SQLInstance)));
Target Login Name: $(ESCAPE_SQUOTE(WMI(TargetLoginName)));
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)));
TextData: $(ESCAPE_SQUOTE(WMI(TextData)));
Success: $(ESCAPE_SQUOTE(WMI(Success)));
'; Setting up WMI Alert to Respond to the Server Scope Permissions Changes
Now we will setup the WMI alert:
set the alert type to "WMI event alert" make sure you use correct WMI namespace:
Note:the namespace will be different for the default instance and for the named instance:
-- 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_SCOPE_GDR_EVENTRead more about the Audit Server Scope GDR Event Class here .
Set the response in alert's properties to execute the job we created earl