Option for temporary excluding a policy

Nov 23, 2015 at 8:26 PM
I've added some functionality to EPM. We are using EPM to monitor several instances at our customers. However, every customer has its own habits for example no backup taken in the weekend. This results in a policy error on monday morning ("No recent Full backup")
So I would like to have an option to (temporary) exclude a policy. This resulted in 3 extra objects:
  • a table called policy.exclusions
  • a function to select the exclusions
  • a stored procedure which removes the policies selected by this function
In order to run this properly, run this stored procedure directly after evaluating the policies and before alerting somebody.

Table:
/*
    Table:      policy.exclusions
    Purpose:    contains information on when a policiy should be ignored
    Author:     wilfred van Dijk (wfvdijk@live.nl)
    
    Example: ignore full backups on monday
    - Policy: "Check Full Backup" 
    > insert into policy.exclusions(EvaluatedPolicy, dayofweek) values("Check Full Backup",4)
*/
use [MDW]
go

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [policy].[Exclusions](
    [EvaluatedServer] [nvarchar](50) NULL,
    [EvaluatedObject] [sysname] NULL,
    [EvaluatedPolicy] [sysname] NULL,
    [StartDate] [date] NULL,
    [EndDate] [date] NULL,
    [StartTime] [time](0) NULL,
    [EndTime] [time](0) NULL,
    [DayOfWeek] [int] NULL,
    [CategoryName] [sysname] NULL,
    [Reason] [nvarchar](64) NULL
) ON [PRIMARY]
GO
Function
/*
    function:   policy.udf_currentexclusions
    Purpose:    returns policies which can be ignored
    Author:     wilfred van Dijk (wfvdijk@live.nl)
    
    Note:       non-null values are combined and interpreted as AND
*/
use [MDW]
go

set quoted_identifier on
go

--#region drop if exists
if exists (select 1 from INFORMATION_SCHEMA.ROUTINES where ROUTINE_NAME = 'udf_CurrentExclusions' and ROUTINE_SCHEMA='policy' and ROUTINE_TYPE='FUNCTION')
    drop function [policy].udf_CurrentExclusions;
if exists (select 1 from INFORMATION_SCHEMA.ROUTINES where ROUTINE_NAME = 'udf_CurrentExclusions' and ROUTINE_SCHEMA='dbo' and ROUTINE_TYPE = 'FUNCTION')
    drop function [dbo].udf_CurrentExclusions;
go
--#endregion

create function policy.udf_CurrentExclusions(@EvaluatedServer nvarchar(50), @EvaluatedPolicy sysname, @EvaluationDateTime smalldatetime, @CategoryName sysname, @EvaluatedObject nvarchar(256))
/*
    sunday = 2^1, monday = 2^2 etc
*/
returns table 
as
    return ( 
                select *
                from policy.Exclusions
                where (EvaluatedServer = @EvaluatedServer or EvaluatedServer is null)
                and (EvaluatedPolicy = @EvaluatedPolicy or EvaluatedPolicy is null)
                and (CategoryName = @CategoryName or CategoryName is null)
                and (charindex(EvaluatedObject, @EvaluatedObject) > 0 or EvaluatedObject is null)
                and cast(@EvaluationDateTime as date) between coalesce(startdate, cast(current_timestamp as date)) and coalesce(enddate, cast(current_timestamp as date))  
                and cast(@EvaluationDateTime as time(0)) between coalesce(starttime, '00:00:00') and coalesce(endtime, '23:59:59')
                and (dayofweek & power(2,datepart(weekday, current_timestamp)) = power(2,datepart(weekday, current_timestamp)) or dayofweek is null)
    )
go
procedure:
/*
    function:   policy.usp_removeexclusions
    Purpose:    deletes policies which can be ignored
    Author:     wilfred van Dijk (wfvdijk@live.nl)
    Parameter:  @RemoveNoTargets {Y|N} removes policies with "no target" marked
                @Execute {Y|N} Deletes policies (Y) or just shows the rows (N)
                
*/
use [MDW]
go
set quoted_identifier on
go

--#region drop if exists
if exists (select 1 from INFORMATION_SCHEMA.ROUTINES where ROUTINE_NAME = 'usp_RemoveExclusions' and ROUTINE_SCHEMA='policy' and ROUTINE_TYPE='PROCEDURE')
    drop procedure policy.usp_RemoveExclusions;
if exists (select 1 from INFORMATION_SCHEMA.ROUTINES where ROUTINE_NAME = 'usp_RemoveExclusions' and ROUTINE_SCHEMA='dbo' and ROUTINE_TYPE='PROCEDURE')
    drop procedure [dbo].usp_RemoveExclusions;
go
--#endregion


create procedure policy.usp_RemoveExclusions @RemoveNoTargets char(1) = 'Y', @Execute char(1) = 'Y'
as
    begin

        set nocount on
        declare @teller int = 0

        if @Execute = 'Y' 
            begin
                delete from [MDW].[policy].PolicyHistory
                where PolicyHistoryID in (
                    SELECT distinct (a.PolicyHistoryID)
                    FROM [MDW].[policy].PolicyHistory a
                    cross apply policy.udf_CurrentExclusions(a.EvaluatedServer, a.EvaluatedPolicy, a.EvaluationDateTime, NULL, NULL) b
                )
                set @teller += @@ROWCOUNT
            end
        else
            begin
                select * from [MDW].[policy].PolicyHistory
                where PolicyHistoryID in (
                    SELECT distinct (a.PolicyHistoryID)
                    FROM [MDW].[policy].PolicyHistory a
                    cross apply policy.udf_CurrentExclusions(a.EvaluatedServer, a.EvaluatedPolicy, a.EvaluationDateTime, NULL, NULL) b
                )
            end

        if @Execute = 'Y' 
            begin
                delete from [MDW].[policy].PolicyHistoryDetail
                where PolicyHistoryDetailID in (
                    SELECT distinct (a.PolicyHistoryDetailID)
                    FROM [MDW].[policy].PolicyHistoryDetail a
                    cross apply policy.udf_CurrentExclusions(a.EvaluatedServer, a.EvaluatedPolicy, a.EvaluationDateTime, a.CategoryName, a.EvaluatedObject) b
                )
                set @teller += @@ROWCOUNT
            end
        else
            begin
                select * from [MDW].[policy].PolicyHistoryDetail
                where PolicyHistoryDetailID in (
                    SELECT distinct (a.PolicyHistoryDetailID)
                    FROM [MDW].[policy].PolicyHistoryDetail a
                    cross apply policy.udf_CurrentExclusions(a.EvaluatedServer, a.EvaluatedPolicy, a.EvaluationDateTime, a.CategoryName, a.EvaluatedObject) b
                )
            end

        if @Execute = 'Y' 
            begin
                delete from [MDW].[policy].EvaluationErrorHistory
                where ErrorHistoryID in (
                    SELECT distinct (a.ErrorHistoryID)
                    FROM [MDW].[policy].EvaluationErrorHistory a
                    cross apply policy.udf_CurrentExclusions(a.EvaluatedServer, a.EvaluatedPolicy, a.EvaluationDateTime, NULL, NULL) b
                )
                set @teller += @@ROWCOUNT
            end
        else
            begin
                select * from [MDW].[policy].EvaluationErrorHistory
                where ErrorHistoryID in (
                    SELECT distinct (a.ErrorHistoryID)
                    FROM [MDW].[policy].EvaluationErrorHistory a
                    cross apply policy.udf_CurrentExclusions(a.EvaluatedServer, a.EvaluatedPolicy, a.EvaluationDateTime, NULL, NULL) b
                )
            end
            
        if @RemoveNoTargets = 'Y' and @execute = 'Y' 
        
            begin
            
                delete from MDW.policy.PolicyHistoryDetail
                where EvaluatedObject = 'No Targets Found' 
                and PolicyResult = 'PASS';
                set @teller += @@ROWCOUNT
                
            end

        if @Execute = 'Y' 
            begin
                delete from Policy.PolicyHistory
                where PolicyHistoryID not in (
                    select distinct(PolicyHistoryId)
                    from Policy.PolicyHistoryDetail
                )
                set @teller += @@ROWCOUNT
            end
        else
            begin
                select * from Policy.PolicyHistory
                where PolicyHistoryID not in (
                    select distinct(PolicyHistoryId)
                    from Policy.PolicyHistoryDetail
                )
            end
            
        print '-- Total rows deleted: ' + cast(@teller as varchar)

    end
go