Files
sql-scripts/TPDT-268 - ACP in task sequence/dba_storedProcedures/sp_ddl_alerts.sql
2024-03-07 16:52:14 +01:00

276 lines
12 KiB
Transact-SQL

USE [HCITools]
GO
IF EXISTS (SELECT * FROM sys.objects o JOIN sys.schemas s ON o.schema_id = s.schema_id WHERE o.name = 'sp_ddl_alerts' AND OBJECTPROPERTY(object_id,N'IsProcedure') = 1 AND s.name = 'dba')
DROP PROCEDURE [dba].[sp_ddl_alerts]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dba].[sp_ddl_alerts]
AS
/*=============================================================================
Explication du traitement realise par la SP
-------------------------------------------
Cette SP est exécutée toute les jours et check les modifications sur les paramètres des bases.
Les résultats sont envoyés par mail
Parametres
----------
Creation : 22.08.2019 / SPE
Modifications : 06.09.19 / SPE : SQL 2014 compatibility modifications
27.09.19 / SPE : Temporary remove trustworth check
09.02.21 / SPE : #TFS62610# - Update all mail configurations to avoid SPAM
17.03.22 - FLA : Change DBA mail
17.08.23 / SPE : OCTPDBA-726: Replace mail profile name APSSQL_MAIL_PROFILE into AzureManagedInstance_dbmail_profile to be SQL managed instances compatible
=============================================================================*/
SET NOCOUNT ON;
/*------------------- Declaration des variables --------------------*/
DECLARE @errno int,
@cvCurrentOrganizationalUnit int,
@subsidiary_id int,
@totAlerts int,
@totDDL int,
@html nvarchar(max),
@errmsg varchar(255),
@email varchar(255),
@subject varchar(255),
@out_default_value varchar(60),
@format varchar(60),
@mailImportance varchar(6),
@ou varchar(3)
/*-------------------------- Traitement ---------------------------*/
BEGIN TRY
/* ------------------------------------------------------------------------------------------------------------------------------------- */
/* \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ 1 : RETRIEVE FORMAT AND OU CODE /////////////////////////////////////////////////// */
/* ------------------------------------------------------------------------------------------------------------------------------------- */
IF EXISTS(SELECT 1 FROM [master].[cfg].[InstanceContext] WHERE Business = 'TPPHAR')
BEGIN
/* Get the cvCurrentOrganizationalUnit */
EXEC arizona.dbo.sp_bmc_Bmc_Applic_Default
@in_job_type = 3,
@in_param_int_1 = null,
@in_param_int_2 = null,
@in_param_varchar_1 = 'cvCurrentOrganizationalUnit',
@out_default_value = @out_default_value OUTPUT,
@out_param_int_1 = null;
SELECT @cvCurrentOrganizationalUnit = convert(int,@out_default_value);
/* Check if we have a value, if not leave this SP */
IF @cvCurrentOrganizationalUnit is null
BEGIN
SELECT @errno = 70001,
@errmsg = '(APS) Error cvCurrentOrganizationalUnit does not exist!';
goto error_99;
END
/* Get the subsidiary id and OU code */
SELECT @subsidiary_id = ou.OU_subsidiary, @ou = ou.OU_Code
FROM arizona.dbo.Organizational_unit ou with (nolock)
WHERE ou.Organizational_unit_ID = @cvCurrentOrganizationalUnit;
/* Check if we have a value, if not leave this SP */
IF @subsidiary_id is null
BEGIN
SELECT @errno = 70001,
@errmsg = '(APS) Error subsidiary_id does not exist!';
goto error_99;
END
/* Get the current format */
SELECT @format = sub.SUB_code
FROM arizona.dbo.Subsidiary sub with (nolock)
WHERE sub.Subsidiary_ID = @subsidiary_id;
/* Check if we have a value, if not leave this SP */
IF @format is null
BEGIN
SELECT @errno = 70001,
@errmsg = '(APS) Error format does not exist!';
goto error_99;
END
/* Change the value into a compatible format */
IF @format = 'COOP'
BEGIN
SET @format = 'CVI'
END
IF @format = 'CENT'
BEGIN
SET @format = 'SUN'
END
IF @format = '000'
BEGIN
SET @format = 'AAI'
END
END
ELSE
BEGIN
SELECT @format = DnsAlias FROM [master].[cfg].[Identity]
SET @ou = ''
END
/* ------------------------------------------------------------------------------------------------------------------------------------- */
/* \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ 2 : RETRIEVE DDL EVENTS /////////////////////////////////////////////////// */
/* ------------------------------------------------------------------------------------------------------------------------------------- */
/* Temp table #AlterRules with alerts template */
CREATE TABLE #AlterRules(AlertRule varchar(100))
/* Template with all DO NOT settings */
INSERT INTO #AlterRules(AlertRule)
VALUES ('AUTO_CLOSE ON'),('AUTO_CREATE_STATISTICS OFF'),('AUTO_SHRINK ON'),('ALLOW_SNAPSHOT_ISOLATION ON'),('ANSI_NULL_DEFAULT OFF'),('ANSI_NULL OFF'),('ANSI_PADDING ON'),
('ANSI_WARNINGS ON'),('ARITHABORT OFF'),('CONCAT_NULL_YIELDS_NULL OFF'),('DB_CHAINING ON'),('DATE_CORRELATION_OPTIMIZATION ON'),('READ_COMMITTED_SNAPSHOT ON'),('NUMERIC_ROUNDABORT OFF'),
('PARAMETERIZATION FORCED'),('QUOTED_IDENTIFIER OFF'),('RECURSIVE_TRIGGERS ON'),('TRUSTWORTHY ON'),('PAGE_VERIFY NONE'),('PAGE_VERIFY TORN_PAGE_DETECTION'),('ENCRYPTION ON')
/* Insert into #DDLAlertLog temp table all DDL events of type alter database for the last 24 hours */
SELECT DA_App_Name,
DA_Host_Name,
DA_Event_Xml.value('(./EVENT_INSTANCE/PostTime)[1]','NVARCHAR(MAX)') AS PostTime,
DA_Event_Xml.value('(./EVENT_INSTANCE/SPID)[1]','NVARCHAR(MAX)') AS SPID,
DA_Event_Xml.value('(./EVENT_INSTANCE/ServerName)[1]','NVARCHAR(MAX)') AS ServerName,
DA_Event_Xml.value('(./EVENT_INSTANCE/LoginName)[1]','NVARCHAR(MAX)') AS LoginName,
DA_Event_Xml.value('(./EVENT_INSTANCE/UserName)[1]','NVARCHAR(MAX)') AS UserName,
DA_Event_Xml.value('(./EVENT_INSTANCE/DatabaseName)[1]','NVARCHAR(MAX)') AS DatabaseName,
DA_Event_Xml.value('(./EVENT_INSTANCE/SchemaName)[1]','NVARCHAR(MAX)') AS SchemaName,
DA_Event_Xml.value('(./EVENT_INSTANCE/ObjectName)[1]','NVARCHAR(MAX)') AS ObjectName,
DA_Event_Xml.value('(./EVENT_INSTANCE/ObjectType)[1]','NVARCHAR(MAX)') AS ObjectType,
DA_Event_Xml.value('(./EVENT_INSTANCE/TSQLCommand/CommandText)[1]','NVARCHAR(MAX)') AS CommandText,
REPLACE(REPLACE(REPLACE(SUBSTRING(LTRIM(RTRIM(REPLACE(REPLACE(REPLACE(REPLACE(DA_Event_Xml.value('(./EVENT_INSTANCE/TSQLCommand/CommandText)[1]','NVARCHAR(MAX)'), CHAR(10), CHAR(32)),CHAR(13), CHAR(32)),CHAR(160), CHAR(32)),CHAR(9),CHAR(32)))), CHARINDEX('SET', REPLACE(DA_Event_Xml.value('(./EVENT_INSTANCE/TSQLCommand/CommandText)[1]','NVARCHAR(MAX)'),' ','')) + 6, LEN(REPLACE(DA_Event_Xml.value('(./EVENT_INSTANCE/TSQLCommand/CommandText)[1]','NVARCHAR(MAX)'),' ',''))),'WITHNO_WAIT',''),'WITHROLLBACKIMMEDIATE',''),' ','') AS CommandAction
INTO #DDLAlertLog
FROM [master].[dba].[DDL_audit]
WHERE DA_Event_Xml.value('(./EVENT_INSTANCE/EventType)[1]','NVARCHAR(MAX)') = 'ALTER_DATABASE'
AND DA_Event_Xml.value('(./EVENT_INSTANCE/PostTime)[1]','NVARCHAR(MAX)') > GETDATE()-1
AND DA_App_Name <> '.Net SqlClient Data Provider'
AND DA_Event_Xml.value('(./EVENT_INSTANCE/TSQLCommand/CommandText)[1]','NVARCHAR(MAX)') not like '%TRUSTWORTHY%'
UNION ALL
SELECT DA_App_Name,
DA_Host_Name,
DA_Event_Xml.value('(./EVENT_INSTANCE/PostTime)[1]','NVARCHAR(MAX)') AS PostTime,
DA_Event_Xml.value('(./EVENT_INSTANCE/SPID)[1]','NVARCHAR(MAX)') AS SPID,
DA_Event_Xml.value('(./EVENT_INSTANCE/ServerName)[1]','NVARCHAR(MAX)') AS ServerName,
DA_Event_Xml.value('(./EVENT_INSTANCE/LoginName)[1]','NVARCHAR(MAX)') AS LoginName,
DA_Event_Xml.value('(./EVENT_INSTANCE/UserName)[1]','NVARCHAR(MAX)') AS UserName,
DA_Event_Xml.value('(./EVENT_INSTANCE/DatabaseName)[1]','NVARCHAR(MAX)') AS DatabaseName,
DA_Event_Xml.value('(./EVENT_INSTANCE/SchemaName)[1]','NVARCHAR(MAX)') AS SchemaName,
DA_Event_Xml.value('(./EVENT_INSTANCE/ObjectName)[1]','NVARCHAR(MAX)') AS ObjectName,
DA_Event_Xml.value('(./EVENT_INSTANCE/ObjectType)[1]','NVARCHAR(MAX)') AS ObjectType,
DA_Event_Xml.value('(./EVENT_INSTANCE/TSQLCommand/CommandText)[1]','NVARCHAR(MAX)') AS CommandText,
'' AS CommandAction
FROM [master].[dba].[DDL_audit]
WHERE DA_Event_Xml.value('(./EVENT_INSTANCE/EventType)[1]','NVARCHAR(MAX)') = 'ALTER_AUTHORIZATION_DATABASE'
AND replace(DA_Event_Xml.value('(./EVENT_INSTANCE/TSQLCommand/CommandText)[1]','NVARCHAR(MAX)'),'[','!') not like '%!sa%'
AND DA_Event_Xml.value('(./EVENT_INSTANCE/PostTime)[1]','NVARCHAR(MAX)') > GETDATE()-1
AND DA_App_Name <> '.Net SqlClient Data Provider'
ORDER BY DA_App_Name DESC
/* ------------------------------------------------------------------------------------------------------------------------------------- */
/* \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ 3 : CREATE AND SEND MAIL /////////////////////////////////////////////////// */
/* ------------------------------------------------------------------------------------------------------------------------------------- */
/* Count total critical alerts and set mail level */
SELECT @totDDL = COUNT(*) FROM #DDLAlertLog AL
SELECT @totAlerts = COUNT(*) FROM #DDLAlertLog AL LEFT JOIN #AlterRules AR ON AL.CommandAction = replace(AR.AlertRule,' ','') WHERE AR.AlertRule is not null OR AL.CommandText like 'alter authorization%'
IF @totAlerts > 0
BEGIN
SET @mailImportance = 'High'
END
ELSE
BEGIN
SET @mailImportance = 'Normal'
END
IF @totDDL > 0
BEGIN
SELECT @email = DML_Recipients
FROM HCITools.dbo.DBA_Mailing_list
WHERE DML_Code = 'DBA_operator'
SET @subject = @format+@ou+': ' + convert(varchar,@totDDL) + ' DDL audit found: Database settings modified! - [' + @@SERVERNAME + ']'
SET @HTML =
N'<body>Server: ' + @format+@ou+'<br />List of all DDL audit events (ALTER DATABASE) for the last day: <br /><br /><table border="1">' +
N'<tr><th>AlertLevel</th><th>Application Name</th><th>Host Name</th><th>Modified date</th><th>SPID</th><th>Server Name</th><th>Login Name</th><th>User Name</th><th>Database Name</th><th>Schema</th><th>Object</th><th>Type</th><th>Command</th></tr>' +
CAST(( SELECT CASE WHEN AR.AlertRule is null AND UPPER(AL.CommandText) not like 'ALTER AUTHORIZATION%' THEN 'INFO' ELSE 'CRITICAL' END AS 'td','',AL.DA_App_Name AS 'td','',
DA_Host_Name AS 'td','',
PostTime AS 'td','',
SPID AS 'td','',
ServerName AS 'td','',
isnull(LoginName,'') AS 'td','',
isnull(UserName,'') AS 'td','',
isnull(DatabaseName,'') AS 'td','',
isnull(SchemaName,'') AS 'td','',
isnull(ObjectName,'') AS 'td','',
isnull(ObjectType,'') AS 'td','',
CommandText AS 'td'
FROM #DDLAlertLog AL
LEFT JOIN #AlterRules AR
ON AL.CommandAction = replace(AR.AlertRule,' ','')
FOR XML PATH('tr'), ELEMENTS ) AS NVARCHAR(MAX)) +
N'</table></body>' ;
/* Get default mailbox profile name */
DECLARE @defaultprofilname varchar(100)
SELECT DISTINCT @defaultprofilname = p.name FROM msdb.dbo.sysmail_profile p JOIN msdb.dbo.sysmail_principalprofile pp ON pp.profile_id = p.profile_id AND pp.is_default = 1
/* SEND MAIL */
EXEC msdb.dbo.sp_send_dbmail
@profile_name = @defaultprofilname,
@recipients = @email,
@body = @html,
@importance = @mailImportance,
@subject = @subject,
@body_format = 'HTML';
END
/* Drop temp tables */
DROP TABLE #DDLAlertLog
DROP TABLE #AlterRules
END TRY
BEGIN CATCH
SELECT @errno = 70003,
@errmsg = 'error on sp_ddl_alerts! ' + error_message()
goto error_99
END CATCH;
/*------------------ Retour au programme appelant -----------------*/
RETURN(@@error);
/*---------------------- Traitement des erreurs ----------------------*/
error_99:
RAISERROR (@errmsg, 16, 1);
RETURN(@errno);
GO