USE [HCITools];
SET NOCOUNT ON;

IF OBJECT_ID('dbo.mon_get_dbMail_status') IS NOT NULL BEGIN
    DROP PROCEDURE dbo.mon_get_dbMail_status;
END;
GO
/*============================================================================= 

  Vérifie que tout les composants nécessaire à db_mail soient actif et configuré, ainsi que l'on ait pas de mail(s) en erreurs
  adapté depuis https://www.mssqltips.com/sqlservertip/5258/sql-server-database-mail-health-check-for-all-sql-servers/

  Les composants vérifiés sont:
	* Sql express 
		db_mail n'est pas disponible sur cette version
	* Est-ce que l'agent SQL tourne ?
	* Est-ce que db_mail est actif ?
	* Est-ce qu'un profil db_mail existe
	* Est-ce qu'un accompte mail existe ?
	* Est-ce que l'agent SQL à la fonction mail active ?
	* Est-ce que le profil db_mail est associé à l'agent SQL ?
	* Est-ce que l'ont trouve des entrées en erreur dans le log des mails dans les derniers X jours (défaut = 7) ?

  Si aucun de ces composants est en echec, la valeur de "mails_are_sent" dans l'output est à 1.
  Si n'importe quel de ces composant empêche l'envoi de mails, ou que des mails sont en erreur, la valeur est 0
  Le champ "notes" contient un détail en toute lettre de ce qui peut bloquer / est bloquant lorsque "mails_are_sent" = 0
 
  Contexte d'utilisation
  ----------------------
    Sur tous les serveurs où db_mail est supposé tourner
  
  Création : 18.10.2022 / TSC
=============================================================================*/
CREATE PROCEDURE dbo.mon_get_dbMail_status @check_failed_mail_in_past_days INT = 7
AS BEGIN
    DECLARE
        @SQLAgentEnabled            INT     = 0
       ,@SQLAgentStarted            INT     = 0
       ,@DBMailEnabled              INT     = 0
       ,@MailProfileEnabled         INT     = 0
       ,@MailAccountEnabled         INT     = 0
       ,@SQLAgentMailEnabled        INT     = 0
       ,@SQLAgentMailProfileEnabled sysname = ''
       ,@failed_email_error         INT     = 0;

    -- SQL Server Agent enabled
    SELECT @SQLAgentEnabled = CAST(value_in_use AS INT)
    FROM sys.configurations
    WHERE [name] = 'Agent XPs';

    -- SQL Server Agent status
    IF (SELECT CAST(SERVERPROPERTY('Edition') AS VARCHAR(30))) NOT LIKE 'Express Edition%' BEGIN
        SELECT @SQLAgentStarted = CASE
                                      WHEN status_desc = 'Running' THEN 1
                                      ELSE 0
                                  END
        FROM sys.dm_server_services
        WHERE SERVICENAME LIKE 'SQL Server Agent%'
		OR servicename LIKE 'sqlagent$%'
		;
    END

    -- SQL Database Mail is enabled
    SELECT @DBMailEnabled = CAST(value_in_use AS INT)
    FROM sys.configurations
    WHERE [name] = 'Database Mail XPs';

    -- @SQLAgentMailEnabled
    SELECT @MailProfileEnabled = CASE
                                     WHEN COUNT(*) > 0 THEN 1
                                     ELSE 0
                                 END
    FROM msdb.dbo.sysmail_profile;

    -- @MailAccountEnabled
    SELECT @MailAccountEnabled = CASE
                                     WHEN COUNT(*) > 0 THEN 1
                                     ELSE 0
                                 END
    FROM msdb.dbo.sysmail_account;

    -- SQL Server Agent is enabled to use Database Mail
    EXECUTE master.dbo.xp_instance_regread
        N'HKEY_LOCAL_MACHINE'
       ,N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent'
       ,N'UseDatabaseMail'
       ,@SQLAgentMailEnabled OUTPUT;

    -- SQL Server Agent is enabled to use Database Mail and Mail Profile is assigned
    EXECUTE master.dbo.xp_instance_regread
        N'HKEY_LOCAL_MACHINE'
       ,N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent'
       ,N'DatabaseMailProfile'
       ,@SQLAgentMailProfileEnabled OUTPUT;

    -- Check if there are failed email send in the last x days
    --SELECT @failed_email_error = CASE
    --								  WHEN COUNT(*) > 0 THEN 1
    --								  ELSE 0 END
    SELECT @failed_email_error = COUNT(1)
	--SELECT *
    FROM msdb.dbo.sysmail_event_log
    WHERE event_type = 'error'
    AND log_date     > DATEADD(DAY, @check_failed_mail_in_past_days * -1, CURRENT_TIMESTAMP);

    /*
	--check each conditions
	SELECT 
		@SQLAgentEnabled AS SQLAgentEnabled
		,@SQLAgentStarted AS SQLAgentStarted
		,@DBMailEnabled AS DBMailEnabled
		,@MailProfileEnabled AS MailProfileEnabled
		,@MailAccountEnabled AS MailAccountEnabled
		,@SQLAgentMailEnabled AS SQLAgentMailEnabled
		,@SQLAgentMailProfileEnabled AS SQLAgentMailProfileEnabled
		,@failed_email_error AS failed_email_error
	;
	*/

    -- Final report
    SELECT
        @@SERVERNAME                                                       AS Server_Name
       ,CAST(CURRENT_TIMESTAMP AS SMALLDATETIME)                           AS Run_Date
       ,@SQLAgentEnabled * @SQLAgentStarted * @DBMailEnabled * @MailProfileEnabled * @MailAccountEnabled
        * @SQLAgentMailEnabled * (CASE WHEN @SQLAgentMailProfileEnabled IS NOT NULL THEN 1 ELSE 0 END)
        * (CASE WHEN ISNULL(@failed_email_error, 0) = 0 THEN 1 ELSE 0 END) AS mails_are_sent
       ,CASE
            WHEN CAST(SERVERPROPERTY('Edition') AS VARCHAR(30)) LIKE 'Express Edition%' THEN
                'Express Edition, DB Mail not supported'
            ELSE
                CASE
                    WHEN @SQLAgentEnabled = 0 THEN 'SQL Agent disabled; '
                    ELSE ''
                END 
				+ 
				CASE
                    WHEN @SQLAgentStarted = 0 THEN 'SQL Agent is stopped; '
                    ELSE ''
                END 
				+ 
				CASE
                    WHEN @DBMailEnabled = 0 THEN 'DB Mail disabled; '
                    ELSE ''
                END 
				+ 
				CASE
					WHEN @MailProfileEnabled = 0 THEN 'Mail Profile disabled; '
					ELSE ''
				END 
				+ 
				CASE
					WHEN @MailAccountEnabled = 0 THEN 'Mail Account disabled; '
					ELSE ''
				END 
				+ 
				CASE
                    WHEN @SQLAgentMailEnabled = 0 THEN 'SQL Agent Mail disabled; '
                    ELSE ''
                END 
				+ 
				CASE
                    WHEN @SQLAgentMailProfileEnabled IS NOT NULL THEN ''
                    ELSE 'SQL Agent Mail Profile disabled; '
                END
                + 
				CASE
					WHEN @failed_email_error > 0 THEN
						'found ' + CAST(@failed_email_error AS VARCHAR(10)) + ' failed email(s) during last '
						+ CONVERT(VARCHAR(5), @check_failed_mail_in_past_days) + ' days; '
					ELSE ''
                END
        END                                                                AS Notes;
END;
GO

--sur ssunbqmsdb02.sunstore.ch\apssql, l'agent est stoppé et il y a des mails en erreur depuis le 12.10.22
EXECUTE HCITools.[dbo].[mon_get_dbMail_status] @check_failed_mail_in_past_days = 30; -- int
