
{"id":7098,"date":"2022-12-16T22:37:06","date_gmt":"2022-12-16T22:37:06","guid":{"rendered":"https:\/\/rax-stg-wp-aws.com\/blogs\/intro-to-mssql-server-audit-feature\/"},"modified":"2026-11-03T19:27:50","modified_gmt":"2026-11-03T19:27:50","slug":"intro-to-mssql-server-audit-feature","status":"publish","type":"blogs","link":"https:\/\/www.rackspace.com\/en-gb\/blogs\/intro-to-mssql-server-audit-feature\/","title":{"rendered":"Intro to MSSQL Server Audit Feature"},"content":{"rendered":"<p><strong>Introduction<\/strong><\/p>\n<p>It is always a challenge to configure audits and capture schema changes for a longer duration in the SQL Server. These details are captured by default traces; however, their retention is limited. Also, it is quite a task to set up SQL audits in every user database.&nbsp;It is not complicated anymore and does not require Enterprise Edition to determine who made the changes to your SQL Server.<\/p>\n<p><em><strong>SQL Server Audits<\/strong><\/em><\/p>\n<p>Auditing an SQL Server or a SQL Server database involves tracking and logging events that occur. SQL Server Audit collects both server and database-level actions as well as groups of actions. Audits are performed at the instance level of the SQL Server. There can be multiple audits per SQL Server instance. Audits also include Database-Level Audit Specifications.<\/p>\n<p><strong>&#8211;<em>SQL Server Audits and its components:<\/em><\/strong><\/p>\n<p><strong>SQL Server Audits<\/strong><\/p>\n<p>\n&#8211; It defines how event information will be kept by an audit at an instance level of the SQL server. An SQL Server audit also specifies the output locations, retentions, and other properties. At an instance level, one or more SQL Server audits are disabled by default.<\/p>\n<p>&#8211; Some of the options configured at SQL Server Audit Level-&nbsp;<\/p>\n<p>&#8211; Audit Destination &#8211; You can store audits to File, Event Viewer Security Logs or Event Viewer Application Logs&nbsp;<\/p>\n<p>\n&nbsp; &nbsp; <em>When Selecting File as your destination you can specify<\/em><br \/>\n&#8211;&nbsp;&nbsp; &nbsp;FILEPATH = Location of audit file<br \/>\n&#8211;&nbsp;&nbsp; &nbsp;MAXSIZE = Max file size<br \/>\n&#8211;&nbsp;&nbsp; &nbsp;MAX_FILES = numbers of file allocated for audits<br \/>\n&#8211;&nbsp;&nbsp; &nbsp;RESERVE_DISK_SPACE = If you want to pre reserve file space for audits files<br \/>\n&#8211;&nbsp;&nbsp; &nbsp;QUEUE_DELAY = As soon as the specified amount of time has passed, SQL Server will queue up the writes from the captured data and write them to the logs.<br \/>\n&#8211;&nbsp;&nbsp; &nbsp;ON_FAILURE = It is possible to specify whether to continue to run or to stop the SQL server instance in case audits fail. An option to continue or to stop is available.<br \/>\n&#8211;&nbsp;&nbsp; &nbsp;WHERE \u2013 we can use this option to filter specific events from audits.<\/p>\n<p>\n&#8211;&nbsp;&nbsp; &nbsp;<strong>Server Audit Specification<\/strong><br \/>\n&#8211;&nbsp;&nbsp; &nbsp;One of the components of an audit is the Server Audit Specification, and it is part of the audit process. The Server Audit specifications are created at the instance level of the SQL Server. All actions from an SQL server instance and many actions from user databases can be captured by a server audit specification.<\/p>\n<p>\n&#8211;&nbsp;&nbsp; &nbsp;In this blog, I\u2019ll be targeting the following server-level actions&nbsp;<\/p>\n<p>&#8220;`<br \/>\n&#8211;&nbsp;&nbsp; &nbsp;DATABASE_ROLE_MEMBER_CHANGE_GROUP<br \/>\n&#8211;&nbsp;&nbsp; &nbsp;SERVER_ROLE_MEMBER_CHANGE_GROUP&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;<br \/>\n&#8211;&nbsp;&nbsp; &nbsp;AUDIT_CHANGE_GROUP<br \/>\n&#8211;&nbsp;&nbsp; &nbsp;SCHEMA_OBJECT_PERMISSION_CHANGE_GROUP<br \/>\n&#8211;&nbsp;&nbsp; &nbsp;SERVER_OBJECT_PERMISSION_CHANGE_GROUP<br \/>\n&#8211;&nbsp;&nbsp; &nbsp;SERVER_PERMISSION_CHANGE_GROUP<br \/>\n&#8211;&nbsp;&nbsp; &nbsp;DATABASE_CHANGE_GROUP<br \/>\n&#8211;&nbsp;&nbsp; &nbsp;DATABASE_OBJECT_CHANGE_GROUP<br \/>\n&#8211;&nbsp;&nbsp; &nbsp;DATABASE_PRINCIPAL_CHANGE_GROUP<br \/>\n&#8211;&nbsp;&nbsp; &nbsp;SCHEMA_OBJECT_CHANGE_GROUP<br \/>\n&#8211;&nbsp;&nbsp; &nbsp;SERVER_OBJECT_CHANGE_GROUP<br \/>\n&#8211;&nbsp;&nbsp; &nbsp;SERVER_PRINCIPAL_CHANGE_GROUP<br \/>\n&#8211;&nbsp;&nbsp; &nbsp;LOGIN_CHANGE_PASSWORD_GROUP<br \/>\n&#8211;&nbsp;&nbsp; &nbsp;SERVER_STATE_CHANGE_GROUP<br \/>\n&#8211;&nbsp;&nbsp; &nbsp;DATABASE_OWNERSHIP_CHANGE_GROUP<br \/>\n&#8211;&nbsp;&nbsp; &nbsp;SERVER_OBJECT_OWNERSHIP_CHANGE_GROUP<br \/>\n&#8211;&nbsp;&nbsp; &nbsp;USER_CHANGE_PASSWORD_GROUP<br \/>\n&#8220;`<\/p>\n<p>\n&nbsp;<strong>Database Audit Specifications<\/strong><br \/>\nA database audit specification only includes actions at the database level to create or modify it in a user database. In the example shared, I\u2019ll be discussing the databases audits and try capturing schema changes in the databases using server audit specifications.<\/p>\n<p>The objective of these Audits :<br \/>\n1.&nbsp;&nbsp; &nbsp;Capture login server-level role modification<br \/>\n2.&nbsp;&nbsp; &nbsp;Capture user role assignment\/modification in all user databases<br \/>\n3.&nbsp;&nbsp; &nbsp;Any changes in audits itself<br \/>\n4.&nbsp;&nbsp; &nbsp;Capture Server, Database, Schema, Object level permissions changes&nbsp;<br \/>\n5.&nbsp;&nbsp; &nbsp;Capture Schema changes from instance to database object level<br \/>\n6.&nbsp;&nbsp; &nbsp;Capture Login password changes<br \/>\n7.&nbsp;&nbsp; &nbsp;Capture in server state changes&nbsp;<\/p>\n<p><strong>Following are the steps to deploy and capture the above details using SQL Server Audits.&nbsp;<\/strong><\/p>\n<p>1.&nbsp;&nbsp; &nbsp;Execute attached scripts to deploy audits and server audit specifications.<\/p>\n<p><img decoding=\"async\" src=\"\/wp-content\/uploads\/2026\/blog_article_images\/26255-body-Picture1_17.png\" alt=\"mssql audit pic 1\" \/><\/p>\n<p>2.&nbsp;&nbsp; &nbsp;This action will create SQL Server Audits with properties described in the following snip. The destination for this audit is a File with default error log location as a path.<\/p>\n<p><img decoding=\"async\" src=\"\/wp-content\/uploads\/2026\/blog_article_images\/26255-body-Picture2_16.png\" alt=\"mssql audit pic 2\" \/><\/p>\n<p>3.&nbsp;&nbsp; &nbsp;Next thing to watch is SQL Server audit specifications and you will see audit specification is created with all actions to capture as discussed.<\/p>\n<p><img decoding=\"async\" src=\"\/wp-content\/uploads\/2026\/blog_article_images\/26255-body-Picture3_16.png\" alt=\"mssql audit pic 3\" \/><\/p>\n<p>4.&nbsp;&nbsp; &nbsp;Testing audits to see if details are being captured&nbsp;<\/p>\n<p>&nbsp; &nbsp; &nbsp; &nbsp; &#8211; a.&nbsp;&nbsp; &nbsp;Create a user database and a table within the User DB<\/p>\n<p><img decoding=\"async\" src=\"\/wp-content\/uploads\/2026\/blog_article_images\/26255-body-Picture4_13.png\" alt=\"mssql audit pic 4\" \/><\/p>\n<p>&nbsp; &nbsp; &nbsp; &nbsp; &#8211; b.&nbsp;&nbsp; &nbsp;Run one more test to change the login password-<\/p>\n<p><img decoding=\"async\" src=\"\/wp-content\/uploads\/2026\/blog_article_images\/26255-body-Picture5_14.png\" alt=\"mssql audit pic 5\" \/><\/p>\n<p>&nbsp; &nbsp; &nbsp; &nbsp; &#8211; c.&nbsp;&nbsp; &nbsp;Let\u2019s see if records are available or not. The following snip indicates changes that are recorded in the audits.<\/p>\n<p><img decoding=\"async\" src=\"\/wp-content\/uploads\/2026\/blog_article_images\/26255-body-Picture6_8.png\" alt=\"mssql audit pic 6\" \/><\/p>\n<p><strong>TSQL Server Script Used For Audit: &#8211;<\/strong><\/p>\n<p>&nbsp;<\/p>\n<p><em>USE [master]&nbsp;<\/em><\/p>\n<p><em>Declare @SmoRoot nvarchar(2000)<br \/>\nDeclare @String Nvarchar(max)<br \/>\nExec master.dbo.xp_instance_regread N&#8217;HKEY_LOCAL_MACHINE&#8217;, N&#8217;SOFTWARE\\Microsoft\\Microsoft SQL Server\\MSSQLServer\\Parameters&#8217;, N&#8217;SQLArg1&#8242;, @SmoRoot OUTPUT<br \/>\nSelect @SmoRoot = SUBSTRING(@SmoRoot,3,len(@SmoRoot)-10)<br \/>\nSet @String = &#8216;CREATE SERVER AUDIT [MSSQL_NativeSQLAudit]<br \/>\nTO FILE&nbsp;<br \/>\n(&nbsp;&nbsp; &nbsp;FILEPATH = N&#8221;&#8217;+@SmoRoot+&#8221;&#8217;<br \/>\n&nbsp;&nbsp; &nbsp;,MAXSIZE = 100 MB<br \/>\n&nbsp;&nbsp; &nbsp;,MAX_FILES = 50<br \/>\n&nbsp;&nbsp; &nbsp;,RESERVE_DISK_SPACE = OFF<br \/>\n)<br \/>\nWITH<br \/>\n(&nbsp;&nbsp; &nbsp;QUEUE_DELAY = 1000<br \/>\n&nbsp;&nbsp; &nbsp;,ON_FAILURE = CONTINUE<br \/>\n)<br \/>\nWHERE (NOT [statement] like &#8221;%ALTER%INDEX%&#8221;&nbsp;<br \/>\nAND NOT [statement] like &#8221;%UPDATE%STATISTICS%&#8221;&nbsp;<br \/>\nAND NOT [STATEMENT] like &#8221;%EVENT%NOTIFICATION%&#8221;&nbsp;<br \/>\nAND NOT [STATEMENT] like &#8221;%ENABLE%TRIGGER%&#8221;&nbsp;<br \/>\nAND NOT [STATEMENT] like &#8221;%DISABLE%TRIGGER%&#8221;&nbsp;<br \/>\nAND NOT [STATEMENT] like &#8221;%OPEN%SYMMETRIC%KEY%&#8221; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;<br \/>\nAND NOT [STATEMENT] like &#8221;%SET%IDENTITY_INSERT%&#8221; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;<br \/>\nAND NOT [STATEMENT] like &#8221;%TRUNCATE%TABLE%&#8221; &nbsp;&nbsp; &nbsp;<br \/>\nAND NOT [Object_name] like &#8221;SqlQueryNotification%&#8221;&nbsp;<br \/>\nAND NOT [server_principal_name] LIKE &#8221;%\\patrol%&#8221;<br \/>\nAND NOT [STATEMENT] like &#8221;%DBCC DBINFO WITH TABLERESULTS%&#8221;&nbsp;<br \/>\nAND NOT [STATEMENT] like &#8221;%RESTORE%VERIFYONLY%&#8221;&nbsp;<br \/>\nAND NOT [STATEMENT] like &#8221;%EXEC %%Object(%&#8221;<br \/>\nAND [database_name]&lt;&gt;&#8221;tempdb&#8221;&nbsp;<br \/>\nAND object_id &lt;&gt; 1<br \/>\nAND (Object_name &lt;&gt; &#8221;BlockingInfo&#8221; AND object_name &lt;&gt; &#8221;MSSQL_AlwaysOn_Monitor&#8221; AND [Object_name]&lt;&gt;&#8221;telemetry_xevents&#8221; )<br \/>\nAND [STATEMENT] &lt;&gt;&#8221;&#8221;)&#8217;<br \/>\n&#8211;print @String<\/em><\/p>\n<p><em>IF EXISTS (SELECT name FROM sys.server_audits WHERE NAME = &#8216;MSSQL_NativeSQLAudit&#8217;)<br \/>\nBEGIN<br \/>\nALTER SERVER AUDIT [MSSQL_NativeSQLAudit] WITH (STATE = OFF)<br \/>\nDROP SERVER AUDIT [MSSQL_NativeSQLAudit]<br \/>\nEND<\/em><\/p>\n<p><em>EXECUTE sp_executesql &nbsp;@String<\/em><\/p>\n<p><em>IF EXISTS (SELECT name FROM sys.server_audit_specifications WHERE NAME = &#8216;MSSQL_ServerAuditSpecification&#8217;)<br \/>\nBEGIN<br \/>\nALTER SERVER AUDIT SPECIFICATION [MSSQL_ServerAuditSpecification] WITH (STATE = OFF)<br \/>\nDROP SERVER AUDIT SPECIFICATION [MSSQL_ServerAuditSpecification]<br \/>\nEND<\/em><\/p>\n<p><em>CREATE SERVER AUDIT SPECIFICATION [MSSQL_ServerAuditSpecification]<br \/>\nFOR SERVER AUDIT [MSSQL_NativeSQLAudit]<br \/>\nADD (DATABASE_ROLE_MEMBER_CHANGE_GROUP),<br \/>\nADD (SERVER_ROLE_MEMBER_CHANGE_GROUP),<br \/>\nADD (AUDIT_CHANGE_GROUP),<br \/>\nADD (SCHEMA_OBJECT_PERMISSION_CHANGE_GROUP),<br \/>\nADD (SERVER_OBJECT_PERMISSION_CHANGE_GROUP),<br \/>\nADD (SERVER_PERMISSION_CHANGE_GROUP),<br \/>\nADD (DATABASE_CHANGE_GROUP),<br \/>\nADD (DATABASE_OBJECT_CHANGE_GROUP),<br \/>\nADD (DATABASE_PRINCIPAL_CHANGE_GROUP),<br \/>\nADD (SCHEMA_OBJECT_CHANGE_GROUP),<br \/>\nADD (SERVER_OBJECT_CHANGE_GROUP),<br \/>\nADD (SERVER_PRINCIPAL_CHANGE_GROUP),<br \/>\nADD (LOGIN_CHANGE_PASSWORD_GROUP),<br \/>\nADD (SERVER_STATE_CHANGE_GROUP),<br \/>\nADD (DATABASE_OWNERSHIP_CHANGE_GROUP),<br \/>\nADD (SERVER_OBJECT_OWNERSHIP_CHANGE_GROUP),<br \/>\nADD (USER_CHANGE_PASSWORD_GROUP)<br \/>\nWITH (STATE = ON)<\/em><\/p>\n<p><em>ALTER SERVER AUDIT [MSSQL_NativeSQLAudit] WITH (STATE = ON)<\/em><\/p>\n<p><strong>Conclusion<\/strong><\/p>\n<p>The SQL Server audits feature can be used in any edition to capture action not just at the instance level, but also at the database level. This is easy to configure and fulfills multiple compliance requirements. It is always important to audit a database system, and the blog will help you in doing the audit correctly.<br \/>\nThe above steps apply to the SQL 2012 Server version and above.&nbsp;<br \/>\n&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Intro to MSSQL Server Audit Feature<\/p>\n","protected":false},"author":2,"featured_media":7100,"menu_order":0,"comment_status":"open","ping_status":"open","template":"","format":"standard","meta":{"content-type":"","nid":"26255","content_type":"blog","created_by":"10130","authored_on":"2023-11-16T22:37:06+00:00","field_article_industries":"","tag_category":"Technical","field_blog_author_text":"by Varun Jha, Manager Cloud Database Services Delivery, Rackspace Technology","seo_description":"Simplify SQL Server audits and schema change tracking. Overcome default trace limitations, configure event logging and enhance security.","field_featured_image":"","insights_image":"\/wp-content\/uploads\/2026\/blog_technical_images\/26255-insights_image-microsoft-technical-blog-1-insights.jpg","field_partners":"","rxt_platforms":"Microsoft SQL","product":"","publisheddate":"2022-12-16T22:37:06","rxt_solutions":"Data Management, Data Strategy & Governance","opengraph_tag":"","x_tag":"","teaser_flag":"Technical Blog","seo_titile":"MSSQL Server Audit Compliance| Rackspace Technology","field_topics":"","field_slug":"intro-to-mssql-server-audit-feature","footnotes":""},"categories":[178],"tags":[204],"class_list":["post-7098","blogs","type-blogs","status-publish","format-standard","has-post-thumbnail","hentry","category-blog","tag-technical"],"_links":{"self":[{"href":"https:\/\/www.rackspace.com\/en-gb\/wp-json\/wp\/v2\/blogs\/7098","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.rackspace.com\/en-gb\/wp-json\/wp\/v2\/blogs"}],"about":[{"href":"https:\/\/www.rackspace.com\/en-gb\/wp-json\/wp\/v2\/types\/blogs"}],"author":[{"embeddable":true,"href":"https:\/\/www.rackspace.com\/en-gb\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.rackspace.com\/en-gb\/wp-json\/wp\/v2\/comments?post=7098"}],"version-history":[{"count":2,"href":"https:\/\/www.rackspace.com\/en-gb\/wp-json\/wp\/v2\/blogs\/7098\/revisions"}],"predecessor-version":[{"id":8960,"href":"https:\/\/www.rackspace.com\/en-gb\/wp-json\/wp\/v2\/blogs\/7098\/revisions\/8960"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.rackspace.com\/en-gb\/wp-json\/wp\/v2\/media\/7100"}],"wp:attachment":[{"href":"https:\/\/www.rackspace.com\/en-gb\/wp-json\/wp\/v2\/media?parent=7098"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.rackspace.com\/en-gb\/wp-json\/wp\/v2\/categories?post=7098"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.rackspace.com\/en-gb\/wp-json\/wp\/v2\/tags?post=7098"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}