Microsoft.SQLServer.Replication.Windows.Monitoring SQL Queries (v7.0.28.0)



Now that the SQL management packs rely heavily on DLLs it’s not easy to determine what the workflows are doing or how they do it. These are the queries used for many of the workflows within this management pack.

-- Microsoft.SQLServer.Replication.Windows.Monitoring (7.0.28.0)

--DistributorPercentOfExpiredSubscriptionsQuery
declare @ParmDefinition nVARCHAR(40);
declare @CountOfSubscription int;
declare @CountOfWrongSubscription int;
SET @ParmDefinition = N'@CountOfSubscriptionOut int OUTPUT';

declare @query nvarchar(max) 
SET @query = N'';
SELECT @query = @query + N'SELECT  COUNT(*) [COUNTER] from (select [publication_id],[subscriber_id],[subscriber_db] FROM   ' + QUOTENAME(name, '"') + '.[dbo].[MSsubscriptions] where subscriber_id > -1 group by [publication_id],[subscriber_id],[subscriber_db]) t UNION ALL '
	FROM sys.databases where is_distributor = 1;

declare @query_tail int 
SET @query_tail = LEN('UNION ALL')
IF (LEN(@query) > @query_tail)
BEGIN
	SET @query = SUBSTRING ( @query ,0 , LEN(@query) - @query_tail )
	SET @query = N'SELECT @CountOfSubscriptionOut = SUM([COUNTER])   FROM ('+@query+N') T0';
END

EXECUTE sp_executesql @query, @ParmDefinition, @CountOfSubscriptionOut = @CountOfSubscription OUTPUT;

SELECT @CountOfSubscription AS TotalCount

SET @query = N'';
SELECT @query = @query + N'EXEC  ' + QUOTENAME(NAME, '"') + '.sys.sp_replmonitorhelpsubscription @mode = 3, @exclude_anonymous = 0, @refreshpolicy = N''0'', @publication_type = 2;
						   EXEC  ' + QUOTENAME(NAME, '"') + '.sys.sp_replmonitorhelpsubscription @mode = 3, @exclude_anonymous = 0, @refreshpolicy = N''0'', @publication_type = 1;
						   EXEC  ' + QUOTENAME(NAME, '"') + '.sys.sp_replmonitorhelpsubscription @mode = 3, @exclude_anonymous = 0, @refreshpolicy = N''0'', @publication_type = 0;'
						
	FROM sys.databases where is_distributor = 1;

EXECUTE (@query)



--DistributionDbAvailabilityQuery
DECLARE @ResultList TABLE (DatabaseName sysname, [State] bit, ErrorCode int, ErrorDescription nvarchar(max));
DECLARE @dbname sysname, @sql nvarchar(max)

DECLARE temp CURSOR LOCAL FOR 
SELECT name from sys.databases where is_distributor = 1;

OPEN temp;

FETCH NEXT FROM temp INTO @dbname;
		
WHILE @@Fetch_Status=0 BEGIN
	SET @sql = N'USE '+ QUOTENAME(@dbname ,'""');
	BEGIN TRY
		EXEC (@sql);
		INSERT INTO @ResultList VALUES (@dbname, 1, 0, '');
	END TRY
	BEGIN CATCH
		INSERT INTO @ResultList VALUES (@dbname, 0, @@ERROR, ERROR_MESSAGE());
	END CATCH;
	FETCH NEXT FROM temp INTO @dbname;
End

CLOSE temp;
DEALLOCATE temp;

SELECT * FROM @ResultList



--SubscriberSubscriptionsQuery
DECLARE @Databases TABLE (
	DatabaseName sysname
)

DECLARE @UnfilteredDatabases TABLE (
	DatabaseName sysname
)

INSERT INTO @UnfilteredDatabases SELECT name FROM sys.databases where name not in ('master','model','msdb','tempdb') and is_distributor <> 1

Declare temp Cursor LOCAL For 
  Select db.DatabaseName 
	From @UnfilteredDatabases db;

declare @sql nvarchar(max),  @dbname sysname, @quotedName nvarchar(max);

Open temp;

Fetch next From temp into @dbname;
While @@Fetch_Status=0 Begin
	set @quotedName = QUOTENAME(@dbname ,'"')
	set @sql = N'USE '+ @quotedName;
	BEGIN TRY
		EXEC (@sql);
		insert into @Databases values (@dbname);
	END TRY
	BEGIN CATCH
	END CATCH;
	Fetch next From temp into @dbname;
End

Close temp;
Deallocate temp;

declare @query nVARCHAR(MAX);
SET @query = N'DECLARE @SUBSCRIPTION_INFO TABLE (
				publisher			sysname not null,
				publisher_db		sysname not null,
				publication			sysname null,
				replication_type	int not NULL,
				subscription_type	int not NULL,
				last_updated		datetime null,
				subscriber_db		sysname not null,
				update_mode			smallint null,
				last_sync_status	int null,
				last_sync_summary	sysname null,
				last_sync_time		datetime null
			   ) ;
				
				DECLARE @COUNTER INT;
				SET @COUNTER = 0;

				';

select  @query = @query + 'BEGIN TRY
						   USE ' + QUOTENAME(DatabaseName, '"') + '; ' + N'
						   INSERT INTO  @SUBSCRIPTION_INFO exec sp_MSenumsubscriptions @subscription_type = ''both''
						   SELECT @COUNTER = @COUNTER +  COUNT(*)  FROM @SUBSCRIPTION_INFO
						   DELETE FROM @SUBSCRIPTION_INFO;
						   END TRY
						   BEGIN CATCH
						   END CATCH
						   '
from @Databases

set @query = @query + 'select @COUNTER SubscriberSubscriptionsCount'

EXEC ( @query)



--DistributorPuplicationsQuery
declare @query nvarchar(max) 
SET @query = N'';
SELECT @query = @query + N'SELECT  COUNT(*) [COUNTER] FROM  ' + QUOTENAME(NAME, '"') + '.[dbo].[MSpublications] UNION ALL '
	FROM sys.databases where is_distributor = 1;

declare @query_tail int 
SET @query_tail = LEN('UNION ALL')
IF (LEN(@query) > @query_tail)
BEGIN
	SET @query = SUBSTRING ( @query ,0 , LEN(@query) - @query_tail )
	SET @query = N'SELECT SUM([COUNTER])  DistributorPublicationsCount FROM ('+@query+N') T0';

	EXEC (@query)
END



--SubscriptionAgentState
DECLARE @Results TABLE (
	[State] int,
	Description int,
	JobId uniqueidentifier,
	JobName nvarchar(max),
	JobLocation nvarchar(max),
	Guid uniqueidentifier
);

IF (SERVERPROPERTY('EngineEdition') = 4)
BEGIN
	SELECT * FROM @Results
	RETURN
END
	
declare @job_id uniqueidentifier;
declare @ParmDefinition nVARCHAR(40);
SET @ParmDefinition = N'@job_id_out uniqueidentifier OUTPUT';

declare @query nvarchar(max) 
SET @query = N'use '+QUOTENAME(@SUBSCRIPTION_DB, '"')+';
 if object_id(''MSmerge_replinfo'', ''U'') is not null
	select top 1 @job_id_out = merge_jobid from MSmerge_replinfo where merge_jobid is not null
 if object_id(''MSreplication_subscriptions'', ''U'') is not null
	select top 1 @job_id_out = cast([agent_id] as uniqueidentifier) from MSreplication_subscriptions where agent_id is not null';

EXECUTE sp_executesql @query, @ParmDefinition, @job_id_out = @job_id OUTPUT;


DECLARE @CALCULATED_DATE_LIST TABLE(schedule_id int,
									schedule_uid UNIQUEIDENTIFIER,
									enabled INT,
									CALCULATED_DATE DATETIME);

declare @schedule_id             int;
declare @schedule_uid			 UNIQUEIDENTIFIER;
declare @enabled				 int;
declare @freq_type				 int;
declare @freq_interval			 int;
declare @freq_subday_type		 int;
declare @freq_subday_interval	 int;
declare @freq_relative_interval	 int;
declare @freq_recurrence_factor	 int;
declare @active_start_date		 int;
declare @active_end_date		 int;
declare @active_start_time		 int;
declare @active_end_time		 int;

DECLARE CURRENT_SCHEDULE_CURSOR CURSOR FOR 
SELECT schedule.schedule_id
      ,schedule.schedule_uid
      ,schedule.enabled
      ,schedule.freq_type
      ,schedule.freq_interval
      ,schedule.freq_subday_type
      ,schedule.freq_subday_interval
      ,schedule.freq_relative_interval
      ,schedule.freq_recurrence_factor
      ,schedule.active_start_date
      ,schedule.active_end_date
      ,schedule.active_start_time
      ,schedule.active_end_time
  FROM msdb.dbo.sysschedules schedule
  JOIN  msdb.[dbo].[sysjobschedules] jobschedule ON schedule.schedule_id = jobschedule.schedule_id
  where jobschedule.job_id = @job_id
  
  

OPEN CURRENT_SCHEDULE_CURSOR

FETCH NEXT FROM CURRENT_SCHEDULE_CURSOR 
INTO @schedule_id           ,        
	 @schedule_uid			,
	 @enabled				,
	 @freq_type				,
	 @freq_interval			,
	 @freq_subday_type		,
	 @freq_subday_interval	,
	 @freq_relative_interval,
	 @freq_recurrence_factor,
	 @active_start_date		,
	 @active_end_date		,
	 @active_start_time		,
	 @active_end_time		;

DECLARE @USED_DAYS TABLE ( DAY_NUMBER INT);

DECLARE @START_DATE DATETIME;
DECLARE @END_DATE DATETIME;
DECLARE @NOW DATETIME 
SET @NOW =  GETDATE(); 
DECLARE @CURRENT_DAY INT 
SET @CURRENT_DAY = DATEPART(DW, @NOW); 

declare @PREVIOUS_CALCULATED_DATE DATETIME 
SET @PREVIOUS_CALCULATED_DATE = NULL;
declare @PREVIOUS_CALCULATED_TIME DATETIME 
SET @PREVIOUS_CALCULATED_TIME = NULL;

WHILE @@FETCH_STATUS = 0
BEGIN
	SET @START_DATE =  CAST(@active_start_date	AS varchar(MAX));
	DECLARE @START_SECOND INT 
	SET @START_SECOND = DATEDIFF(second,0,Stuff(Stuff(right('000000'+Cast(@active_start_time as Varchar),6),3,0,':'),6,0,':'));
	SET @START_DATE = DATEADD(SECOND, @START_SECOND, @START_DATE);

	SET @END_DATE =  CAST(@active_end_date	AS varchar(MAX));
	DECLARE @END_SECOND INT 
	SET @END_SECOND = DATEDIFF(second,0,Stuff(Stuff(right('000000'+Cast(@active_end_time as Varchar),6),3,0,':'),6,0,':'));
	SET @END_DATE = DATEADD(SECOND, @END_SECOND, @END_DATE);

	SET @PREVIOUS_CALCULATED_DATE = NULL;

	IF   NOT (@enabled = 0 OR @START_DATE > @NOW OR @END_DATE < @NOW)
	BEGIN
		SET @PREVIOUS_CALCULATED_DATE = @START_DATE;
		
		IF @freq_type = 4  OR --Daily
		   @freq_type = 8  OR -- Weekly
		   @freq_type = 16  OR -- Monthly
		   @freq_type = 32   -- Monthly, relative to freq_interval
		BEGIN
			-- GLOBAL VARS
			DECLARE @ITER_DATE DATETIME 
			SET @ITER_DATE = @START_DATE;
			DECLARE @ITERATOR INT 
			SET @ITERATOR = 0;
			DECLARE @DAY_COUNTER INT 
			SET @DAY_COUNTER = 0;
			DECLARE @WEEK_COUNTER INT  
			SET @WEEK_COUNTER = 0;
			DECLARE @MONTH_COUNTER INT 
			SET @MONTH_COUNTER = 0;

			IF @freq_type = 4  --Daily
			BEGIN
				SET @DAY_COUNTER = 0;
				WHILE @ITER_DATE < @NOW
					BEGIN
						IF (@DAY_COUNTER % @freq_interval) = 0
							SET @PREVIOUS_CALCULATED_DATE = @ITER_DATE;
						SET @DAY_COUNTER = @DAY_COUNTER + 1; 
						SET @ITER_DATE = DATEADD(DAY, 1, @ITER_DATE);
					END
			END

			IF @freq_type = 8  -- Weekly
			BEGIN
				SET @ITERATOR = 1;
				-- FIND USED DAY OF WEEK
				WHILE @ITERATOR <= 7
					BEGIN
						DECLARE @DEGREE_OF_TWO INT 
						SET @DEGREE_OF_TWO = CAST(POWER(2, @ITERATOR-1) AS INT);
						IF @freq_interval & @DEGREE_OF_TWO = @DEGREE_OF_TWO
							INSERT INTO @USED_DAYS VALUES(@ITERATOR);
						SET @ITERATOR= @ITERATOR + 1;
					END

				-- LOOP ON ALL DAYS FROM START TO NOW AND CHECK IF CONDITION PASSED
				DECLARE @IS_PREVIOUS_RUNS_EXIST BIT 
				SET @IS_PREVIOUS_RUNS_EXIST = 0;
				SET @WEEK_COUNTER  = 0;

				WHILE @ITER_DATE < @NOW
					BEGIN
						IF EXISTS (SELECT * FROM @USED_DAYS WHERE DAY_NUMBER = DATEPART(DW, @ITER_DATE))
							BEGIN
								SET @IS_PREVIOUS_RUNS_EXIST = 1;
								IF (@WEEK_COUNTER % @freq_recurrence_factor) = 0
									SET @PREVIOUS_CALCULATED_DATE = @ITER_DATE; 
							END

						IF @IS_PREVIOUS_RUNS_EXIST = 1 AND DATEPART(DW, @ITER_DATE) = 7
							SET @WEEK_COUNTER = @WEEK_COUNTER + 1;

						SET @ITER_DATE = DATEADD(DAY, 1, @ITER_DATE);
					END
				-- CLEAR TABLE @USED_DAYS
				DELETE FROM @USED_DAYS
			END 

			IF @freq_type = 16  -- Monthly
			BEGIN
				SET @PREVIOUS_CALCULATED_DATE = NULL
				DECLARE @DAYS_IN_MONTH INT;

				IF DATEPART(DAY, @START_DATE) > @freq_interval 
					BEGIN
						SET @ITERATOR = 1;
						-- FIND FIRST RUN
						WHILE @ITERATOR < 3
							BEGIN
								SET @START_DATE = DATEADD(MONTH, 1, @START_DATE);
								SET @DAYS_IN_MONTH  = DAY(DATEADD(DD,-1,DATEADD(MM,DATEDIFF(MM,-1,@START_DATE),0)))
								IF @DAYS_IN_MONTH > @freq_interval
									SET @START_DATE = CAST(DATEPART(YEAR, @START_DATE) AS VARCHAR)+ '-' +CAST(DATEPART(MONTH, @START_DATE) AS VARCHAR)+ '-' +CAST(@freq_interval AS VARCHAR) + ' ' + Stuff(Stuff(right('000000'+Cast(@active_start_time as Varchar),6),3,0,':'),6,0,':');
								SET @ITERATOR = @ITERATOR + 1;
							END
					END
				ELSE	
					SET @START_DATE = CAST(DATEPART(YEAR, @START_DATE) AS VARCHAR)+ '-' +CAST(DATEPART(MONTH, @START_DATE) AS VARCHAR)+ '-' +CAST(@freq_interval AS VARCHAR) + ' ' + Stuff(Stuff(right('000000'+Cast(@active_start_time as Varchar),6),3,0,':'),6,0,':');


				SET @ITER_DATE = @START_DATE

				IF @START_DATE > @NOW
					SET @START_DATE = NULL;

				SET @PREVIOUS_CALCULATED_DATE = @START_DATE;

				SET @MONTH_COUNTER = 0;
				WHILE @ITER_DATE < @NOW
					BEGIN
						SET @DAYS_IN_MONTH  = DAY(DATEADD(DD,-1,DATEADD(MM,DATEDIFF(MM,-1,@ITER_DATE),0)))
						IF (@MONTH_COUNTER % @freq_recurrence_factor) = 0 AND @DAYS_IN_MONTH > @freq_interval
							SET @PREVIOUS_CALCULATED_DATE = @ITER_DATE; 
						SET @MONTH_COUNTER = @MONTH_COUNTER + 1; 
						SET @ITER_DATE = DATEADD(MONTH, 1, @ITER_DATE);
					END
			END

			IF @freq_type = 32   -- Monthly, relative to freq_interval
			BEGIN
				SET @PREVIOUS_CALCULATED_DATE = NULL
				--1 =  Sunday
				--2 =  Monday
				--3 =  Tuesday
				--4 =  Wednesday
				--5 =  Thursday
				--6 =  Friday
				--7 =  Saturday
				--8 =  Day
				--9 =  Weekday
				--10 = Weekend day
				DECLARE @IS_SUNDAY	    BIT 
				SET @IS_SUNDAY = 0;
				DECLARE @IS_MONDAY	    BIT 
				SET @IS_MONDAY = 0;
				DECLARE @IS_TUESDAY	    BIT 
				SET @IS_TUESDAY = 0;
				DECLARE @IS_WEDNESDAY   BIT 
				SET @IS_WEDNESDAY = 0;
				DECLARE @IS_THURSDAY    BIT 
				SET @IS_THURSDAY = 0;
				DECLARE @IS_FRIDAY	    BIT 
				SET @IS_FRIDAY = 0;
				DECLARE @IS_SATURDAY    BIT 
				SET @IS_SATURDAY = 0;
				DECLARE @IS_DAY		    BIT 
				SET @IS_DAY = 0;
				DECLARE @IS_WEEKDAY	    BIT 
				SET @IS_WEEKDAY = 0;
				DECLARE @IS_WEEKEND_DAY BIT 
				SET @IS_WEEKEND_DAY = 0;

				IF @freq_interval = 1
					SET @IS_SUNDAY	    = 1;
				IF @freq_interval = 2
					SET @IS_MONDAY	    = 1;
				IF @freq_interval = 3
					SET @IS_TUESDAY	    = 1;
				IF @freq_interval = 4
					SET @IS_WEDNESDAY   = 1;
				IF @freq_interval = 5
					SET @IS_THURSDAY    = 1;
				IF @freq_interval = 6
					SET @IS_FRIDAY	    = 1;
				IF @freq_interval = 7
					SET @IS_SATURDAY    = 1;
				IF @freq_interval = 8
					SET @IS_DAY		    = 1;
				IF @freq_interval = 9
					SET @IS_WEEKDAY	    = 1;
				IF @freq_interval = 10
					SET @IS_WEEKEND_DAY = 1;


				--1 = First
				--2 = Second
				--4 = Third
				--8 = Fourth
				--16 = Last
				DECLARE @EVERY INT;
				DECLARE @IS_LAST BIT 
				SET @IS_LAST = 0;

				IF @freq_relative_interval = 16
					SET @IS_LAST = 1
				ELSE
					SET @EVERY = CAST(LOG(@freq_relative_interval)/LOG(2) AS INT) + 1;
				
				DECLARE @CURRENT_DAY_COUNTER INT 
				SET @CURRENT_DAY_COUNTER = 0;
				SET @MONTH_COUNTER = 0;
				DECLARE @PREVIOUS_MONTH INT 
				SET @PREVIOUS_MONTH = DATEPART(MONTH, @START_DATE);
				WHILE @ITER_DATE < @NOW
					BEGIN
						IF @IS_SUNDAY = 1 AND DATEPART(DW, @ITER_DATE) = 1
							IF @IS_LAST = 1 AND (@MONTH_COUNTER % @freq_recurrence_factor) = 0 AND (DAY(DATEADD(DD,-1,DATEADD(MM,DATEDIFF(MM,-1,@ITER_DATE),0))) - DATEPART(DAY, @ITER_DATE)) < 7 --IF DAYS TO END OF MONTH < 7
								SET @PREVIOUS_CALCULATED_DATE = @ITER_DATE; 
							ELSE
							BEGIN
								 SET @CURRENT_DAY_COUNTER = @CURRENT_DAY_COUNTER + 1;
								 IF (@MONTH_COUNTER % @freq_recurrence_factor) = 0 AND @CURRENT_DAY_COUNTER = @EVERY
									SET @PREVIOUS_CALCULATED_DATE = @ITER_DATE;
							END

						IF @IS_MONDAY = 1 AND DATEPART(DW, @ITER_DATE) = 2
							IF @IS_LAST = 1 AND (@MONTH_COUNTER % @freq_recurrence_factor) = 0 AND (DAY(DATEADD(DD,-1,DATEADD(MM,DATEDIFF(MM,-1,@ITER_DATE),0))) - DATEPART(DAY, @ITER_DATE)) < 7 --IF DAYS TO END OF MONTH < 7
								SET @PREVIOUS_CALCULATED_DATE = @ITER_DATE; 
							ELSE
							BEGIN
								 SET @CURRENT_DAY_COUNTER = @CURRENT_DAY_COUNTER + 1;
								 IF (@MONTH_COUNTER % @freq_recurrence_factor) = 0 AND @CURRENT_DAY_COUNTER = @EVERY
									SET @PREVIOUS_CALCULATED_DATE = @ITER_DATE;
							END

						IF @IS_TUESDAY = 1 AND DATEPART(DW, @ITER_DATE) = 3
							IF @IS_LAST = 1 AND (@MONTH_COUNTER % @freq_recurrence_factor) = 0 AND (DAY(DATEADD(DD,-1,DATEADD(MM,DATEDIFF(MM,-1,@ITER_DATE),0))) - DATEPART(DAY, @ITER_DATE)) < 7 --IF DAYS TO END OF MONTH < 7
								SET @PREVIOUS_CALCULATED_DATE = @ITER_DATE; 
							ELSE
							BEGIN
								 SET @CURRENT_DAY_COUNTER = @CURRENT_DAY_COUNTER + 1;
								 IF (@MONTH_COUNTER % @freq_recurrence_factor) = 0 AND @CURRENT_DAY_COUNTER = @EVERY
									SET @PREVIOUS_CALCULATED_DATE = @ITER_DATE;
							END

						IF @IS_WEDNESDAY = 1 AND DATEPART(DW, @ITER_DATE) = 4
							IF @IS_LAST = 1  AND (@MONTH_COUNTER % @freq_recurrence_factor) = 0 AND (DAY(DATEADD(DD,-1,DATEADD(MM,DATEDIFF(MM,-1,@ITER_DATE),0))) - DATEPART(DAY, @ITER_DATE)) < 7 --IF DAYS TO END OF MONTH < 7
								SET @PREVIOUS_CALCULATED_DATE = @ITER_DATE; 
							ELSE
							BEGIN
								 SET @CURRENT_DAY_COUNTER = @CURRENT_DAY_COUNTER + 1;
								 IF (@MONTH_COUNTER % @freq_recurrence_factor) = 0 AND @CURRENT_DAY_COUNTER = @EVERY
									SET @PREVIOUS_CALCULATED_DATE = @ITER_DATE;
							END

						IF @IS_THURSDAY = 1 AND DATEPART(DW, @ITER_DATE) = 5
							IF @IS_LAST = 1 AND (@MONTH_COUNTER % @freq_recurrence_factor) = 0 AND (DAY(DATEADD(DD,-1,DATEADD(MM,DATEDIFF(MM,-1,@ITER_DATE),0))) - DATEPART(DAY, @ITER_DATE)) < 7 --IF DAYS TO END OF MONTH < 7
								SET @PREVIOUS_CALCULATED_DATE = @ITER_DATE; 
							ELSE
							BEGIN
								 SET @CURRENT_DAY_COUNTER = @CURRENT_DAY_COUNTER + 1;
								 IF (@MONTH_COUNTER % @freq_recurrence_factor) = 0 AND @CURRENT_DAY_COUNTER = @EVERY
									SET @PREVIOUS_CALCULATED_DATE = @ITER_DATE;
							END

						IF @IS_FRIDAY = 1 AND DATEPART(DW, @ITER_DATE) = 6
							IF @IS_LAST = 1 AND (@MONTH_COUNTER % @freq_recurrence_factor) = 0 AND (DAY(DATEADD(DD,-1,DATEADD(MM,DATEDIFF(MM,-1,@ITER_DATE),0))) - DATEPART(DAY, @ITER_DATE)) < 7 --IF DAYS TO END OF MONTH < 7
								SET @PREVIOUS_CALCULATED_DATE = @ITER_DATE; 
							ELSE
							BEGIN
								 SET @CURRENT_DAY_COUNTER = @CURRENT_DAY_COUNTER + 1;
								 IF (@MONTH_COUNTER % @freq_recurrence_factor) = 0 AND @CURRENT_DAY_COUNTER = @EVERY
									SET @PREVIOUS_CALCULATED_DATE = @ITER_DATE;
							END

						IF @IS_SATURDAY = 1 AND DATEPART(DW, @ITER_DATE) = 7
							IF @IS_LAST = 1 AND (@MONTH_COUNTER % @freq_recurrence_factor) = 0 AND (DAY(DATEADD(DD,-1,DATEADD(MM,DATEDIFF(MM,-1,@ITER_DATE),0))) - DATEPART(DAY, @ITER_DATE)) < 7 --IF DAYS TO END OF MONTH < 7
								SET @PREVIOUS_CALCULATED_DATE = @ITER_DATE; 
							ELSE
							BEGIN
								 SET @CURRENT_DAY_COUNTER = @CURRENT_DAY_COUNTER + 1;
								 IF (@MONTH_COUNTER % @freq_recurrence_factor) = 0 AND @CURRENT_DAY_COUNTER = @EVERY
									SET @PREVIOUS_CALCULATED_DATE = @ITER_DATE;
							END

						IF @IS_DAY = 1 
							IF @IS_LAST = 1 AND (@MONTH_COUNTER % @freq_recurrence_factor) = 0 AND (DAY(DATEADD(DD,-1,DATEADD(MM,DATEDIFF(MM,-1,@ITER_DATE),0))) - DATEPART(DAY, @ITER_DATE))  = 0 --IF LAST DAY OF MONTH 
								SET @PREVIOUS_CALCULATED_DATE = @ITER_DATE; 
							ELSE IF (@MONTH_COUNTER % @freq_recurrence_factor) = 0 AND @EVERY = DATEPART(DAY, @ITER_DATE)
									SET @PREVIOUS_CALCULATED_DATE = @ITER_DATE;
							 
						IF @IS_WEEKDAY = 1 AND 
							(DATEPART(DW, @ITER_DATE) = 2 OR
							 DATEPART(DW, @ITER_DATE) = 3 OR
							 DATEPART(DW, @ITER_DATE) = 4 OR
							 DATEPART(DW, @ITER_DATE) = 5 OR
							 DATEPART(DW, @ITER_DATE) = 6)
							IF @IS_LAST = 1 AND (@MONTH_COUNTER % @freq_recurrence_factor) = 0 AND (DAY(DATEADD(DD,-1,DATEADD(MM,DATEDIFF(MM,-1,@ITER_DATE),0))) - DATEPART(DAY, @ITER_DATE)) < 3 -- CHECK LAST 3 LFY 
								SET @PREVIOUS_CALCULATED_DATE = @ITER_DATE; 
							ELSE
								BEGIN
									 SET @CURRENT_DAY_COUNTER = @CURRENT_DAY_COUNTER + 1;
									 IF (@MONTH_COUNTER % @freq_recurrence_factor) = 0 AND @CURRENT_DAY_COUNTER = @EVERY
										SET @PREVIOUS_CALCULATED_DATE = @ITER_DATE;
								END

						IF @IS_WEEKEND_DAY = 1 AND 
							(DATEPART(DW, @ITER_DATE) = 1 OR
							 DATEPART(DW, @ITER_DATE) = 7)
							IF @IS_LAST = 1 AND (@MONTH_COUNTER % @freq_recurrence_factor) = 0 AND (DAY(DATEADD(DD,-1,DATEADD(MM,DATEDIFF(MM,-1,@ITER_DATE),0))) - DATEPART(DAY, @ITER_DATE)) < 6 --IF DAYS TO END OF MONTH < 7
								SET @PREVIOUS_CALCULATED_DATE = @ITER_DATE; 
							ELSE
								BEGIN
									 SET @CURRENT_DAY_COUNTER = @CURRENT_DAY_COUNTER + 1;
									 IF (@MONTH_COUNTER % @freq_recurrence_factor) = 0 AND @CURRENT_DAY_COUNTER = @EVERY
										SET @PREVIOUS_CALCULATED_DATE = @ITER_DATE;
								END
						
						SET @ITER_DATE = DATEADD(DAY, 1, @ITER_DATE);
						IF @PREVIOUS_MONTH <> DATEPART(MONTH, @ITER_DATE)
							SET @MONTH_COUNTER  = @MONTH_COUNTER + 1;
					END
			END
						
			IF @PREVIOUS_CALCULATED_DATE IS NOT NULL AND @freq_subday_type <> 1 -- ONCE AT DAY
				BEGIN
					DECLARE @MULTIPLIER INT 
					SET @MULTIPLIER = @freq_subday_interval;
					IF CAST(FLOOR(CAST(@NOW AS FLOAT)) AS DATETIME) = CAST(FLOOR(CAST(@PREVIOUS_CALCULATED_DATE AS FLOAT)) AS DATETIME)
						BEGIN
							DECLARE @NOW_SECONDS INT 
							SET @NOW_SECONDS = DATEDIFF(SECOND, CAST(FLOOR(CAST(@NOW AS FLOAT)) AS DATETIME), @NOW)
							IF @NOW_SECONDS < @END_SECOND
								SET @END_SECOND = @NOW_SECONDS
						END
					IF @freq_subday_type = 4
						SET @MULTIPLIER = @freq_subday_interval*60;
					IF @freq_subday_type = 8
						SET @MULTIPLIER = @freq_subday_interval*3600;
					SET @PREVIOUS_CALCULATED_DATE = DATEADD(SECOND, (@END_SECOND - @START_SECOND)/@MULTIPLIER*@MULTIPLIER, @PREVIOUS_CALCULATED_DATE);

					

						
				END
		END
	END
	
	
	
	INSERT INTO @CALCULATED_DATE_LIST VALUES(@schedule_id, @schedule_uid, @enabled, @PREVIOUS_CALCULATED_DATE);

	FETCH NEXT FROM CURRENT_SCHEDULE_CURSOR 
	INTO @schedule_id           ,        
		 @schedule_uid			,
		 @enabled				,
		 @freq_type				,
		 @freq_interval			,
		 @freq_subday_type		,
		 @freq_subday_interval	,
		 @freq_relative_interval,
		 @freq_recurrence_factor,
		 @active_start_date		,
		 @active_end_date		,
		 @active_start_time		,
		 @active_end_time		;
END
CLOSE CURRENT_SCHEDULE_CURSOR;
DEALLOCATE CURRENT_SCHEDULE_CURSOR;


DECLARE @job_is_continuous int 
		SET @job_is_continuous =	CASE
										WHEN EXISTS(
													SELECT 1 FROM msdb.dbo.sysjobschedules sjs
													JOIN msdb.dbo.sysschedules ss ON ss.schedule_id = sjs.schedule_id
													WHERE ss.enabled = 1 AND ss.freq_type = 64 AND sjs.job_id = @job_id
													) THEN 1
										ELSE 0
									END

DECLARE @XpJobList TABLE (
job_id                UNIQUEIDENTIFIER NOT NULL,
last_run_date         INT              NOT NULL,
last_run_time         INT              NOT NULL,
next_run_date         INT              NOT NULL,
next_run_time         INT              NOT NULL,
next_run_schedule_id  INT              NOT NULL,
requested_to_run      INT              NOT NULL, -- BOOL
request_source        INT              NOT NULL,
request_source_id     sysname          COLLATE database_default NULL,
running               INT              NOT NULL, -- BOOL
current_step          INT              NOT NULL,
current_retry_attempt INT              NOT NULL,
job_state             INT              NOT NULL
)

DECLARE @can_see_all_running_jobs INT
DECLARE @job_owner   sysname

SELECT @can_see_all_running_jobs = ISNULL(IS_SRVROLEMEMBER(N'sysadmin'), 0)
IF (@can_see_all_running_jobs = 0)
BEGIN
	declare @table_role table (rolecount	int null);
	declare @query_role nvarchar(max)
	set @query_role = 'USE msdb; ' + 
		'SELECT ISNULL(IS_MEMBER(N''SQLAgentReaderRole''), 0)'
	insert into @table_role exec (@query_role) 
		
	SELECT @can_see_all_running_jobs = rolecount from @table_role 
END
SELECT @job_owner = SUSER_SNAME()

IF (SELECT value from sys.configurations where name = 'Agent XPs') = 1
BEGIN
	IF ((@@microsoftversion / 0x01000000) >= 8) -- SQL Server 8.0 or greater
		INSERT INTO @XpJobList
		EXECUTE master.dbo.xp_sqlagent_enum_jobs @can_see_all_running_jobs, @job_owner,  @job_id
	ELSE
		INSERT INTO @XpJobList
		EXECUTE master.dbo.xp_sqlagent_enum_jobs @can_see_all_running_jobs, @job_owner
END

--Get Job history entries

DECLARE @run_date_outcome datetime
DECLARE @run_duration_outcome int
DECLARE @run_status_outcome int
DECLARE @run_date datetime
DECLARE @run_duration int
DECLARE @run_end_date datetime
DECLARE @run_status int

SELECT TOP 1
	@run_date_outcome = sjso.run_date_outcome
	,@run_duration_outcome = sjso.run_duration_outcome
	,@run_status_outcome = sjso.run_status_outcome 
	,@run_date = sja.run_date
	,@run_duration = sja.run_duration
	,@run_status = sja.run_status
FROM	
	(
		SELECT TOP 1
			sjs.job_id
			,CASE 
				WHEN (last_run_date IS NOT NULL AND last_run_time IS NOT NULL) AND (last_run_date <> 0) THEN msdb.dbo.agent_datetime(last_run_date,last_run_time)
				ELSE NULL
			END run_date_outcome
			,(CASE
			--hours, minutes and seconds
				WHEN LEN(last_run_duration) > 4 THEN CONVERT(VARCHAR(4),LEFT(last_run_duration,LEN(last_run_duration)-4)) * 3600
				+ LEFT(RIGHT(last_run_duration,4),2) * 60 + RIGHT(last_run_duration,2)
				--minutes and seconds
				WHEN LEN(last_run_duration) = 4 THEN LEFT(last_run_duration,2) * 60 + RIGHT(last_run_duration,2)
				WHEN LEN(last_run_duration) = 3 THEN LEFT(last_run_duration,1) * 60 + RIGHT(last_run_duration,2)
				ELSE --only seconds    
					RIGHT(last_run_duration,2) 
				END) run_duration_outcome
			,sjs.last_run_outcome run_status_outcome
		FROM msdb.dbo.sysjobservers sjs
		WHERE last_run_duration is not null AND sjs.job_id = @job_id
	) sjso
	OUTER APPLY
	(
		SELECT TOP 1
			msdb.dbo.agent_datetime(sjh.run_date, sjh.run_time) run_date
			,(CASE
			--hours, minutes and seconds
				WHEN LEN(run_duration) > 4 THEN CONVERT(VARCHAR(4),LEFT(run_duration,LEN(run_duration)-4)) * 3600
				+ LEFT(RIGHT(run_duration,4),2) * 60 + RIGHT(run_duration,2)
				--minutes and seconds
				WHEN LEN(run_duration) = 4 THEN LEFT(run_duration,2) * 60 + RIGHT(run_duration,2)
				WHEN LEN(run_duration) = 3 THEN LEFT(run_duration,1) * 60 + RIGHT(run_duration,2)
				ELSE --only seconds    
					RIGHT(run_duration,2) 
				END) run_duration
				,sjh.run_status
		FROM msdb.dbo.sysjobhistory sjh
		WHERE sjh.job_id = sjso.job_id
			AND msdb.dbo.agent_datetime(sjh.run_date, sjh.run_time) > dateadd(SECOND, sjso.run_duration_outcome, sjso.run_date_outcome)
		ORDER BY sjh.run_date desc, run_time desc, run_duration desc
	) sja




DECLARE @agent_is_running int
DECLARE @current_step int
DECLARE @retry_attempt int
DECLARE @xp_job_state int

SELECT TOP 1
	@agent_is_running = xjl.running
	,@current_step =	CASE xjl.current_step
							WHEN 0 THEN NULL
							ELSE xjl.current_step
						END
	,@retry_attempt = xjl.current_retry_attempt
	,@xp_job_state = xjl.job_state
FROM @XpJobList xjl
WHERE xjl.job_id = @job_id


DECLARE @JOB_NAME nvarchar(max)
DECLARE @SCHEDULE_ENABLED int
DECLARE @JOB_ENABLED int
DECLARE @JOB_LOCATION nVARCHAR(MAX)

DECLARE @CALCULATED_DATE datetime

DECLARE @current_job_state int
DECLARE @current_job_description int
DECLARE @current_date datetime 
SET @current_date = GETDATE()


SELECT TOP 1
	@JOB_NAME = job.name
	,@SCHEDULE_ENABLED = JS.enabled
	,@JOB_ENABLED = job.enabled
	,@JOB_LOCATION = @@SERVERNAME
	,@CALCULATED_DATE = JS.CALCULATED_DATE
	FROM  [msdb].[dbo].[sysjobs] job 
	LEFT JOIN (SELECT JS.job_id,MAX(enabled) enabled, MAX(CALCULATED_DATE) CALCULATED_DATE 
		FROM msdb.[dbo].[sysjobschedules] JS 
		JOIN @CALCULATED_DATE_LIST LIST ON LIST.schedule_id = JS.schedule_id
		GROUP BY JS.job_id) JS ON job.job_id = JS.job_id
	LEFT JOIN msdb.dbo.sysjobservers jobservers ON job.job_id = jobservers.job_id
	where job.job_id = @job_id



SET @current_job_state = 4--'Unknown'
SET @current_job_description = 11--'Unknown' 

--IF @job_id = '374B974A-1EFB-4D60-82E1-4136828F8FE8'
--	SET @current_job_description = 11

IF @JOB_ENABLED = 0 
BEGIN
	SET @current_job_state = 2--'Warning'
	SET @current_job_description = 3--'Job is disabled'
END
ELSE IF  @SCHEDULE_ENABLED = 0 AND @JOB_ENABLED = 1
BEGIN
	SET @current_job_state = 2--'Warning'
	SET @current_job_description = 12--'Job is enabled but schedule is disabled'
END
ELSE IF @job_is_continuous = 1
	IF @agent_is_running = 1 --continuous job is running
	BEGIN
		SET @current_job_state =	CASE @xp_job_state
										WHEN 3 THEN 2--'Warning'
										ELSE 3--'Healhy'
									END 
								
		SET @current_job_description =	CASE @xp_job_state
											WHEN 3 THEN 10--'Job is retry'
											ELSE 2--'Job is running'
										END 
	END
	ELSE
	BEGIN
		SET @current_job_state = 2--'Warning'
		SET @current_job_description = 15--'Agent is not running'
	END
	--end of continuous jobs processing
	ELSE
	BEGIN
		--DECLARE @curr_time_last_run_is_valid bit
		--SET @curr_time_last_run_is_valid = 0
		--IF @run_end_date IS NOT NULL
		--	IF ABS(datediff(MINUTE,@run_end_date,@current_date)) <= @estimated_job_duration
		--		SET @curr_time_last_run_is_valid = 1

		IF @SCHEDULE_ENABLED IS NULL
		BEGIN
			IF (@run_status_outcome IS NULL) AND (@CALCULATED_DATE IS NULL) AND ((@run_date IS NULL) OR (@run_end_date IS NOT NULL /*AND @curr_time_last_run_is_valid = 0*/))
			BEGIN
				SET @current_job_state = 2--'Warning'
				SET @current_job_description = 9--'Job exist but never run and has not shcedule'
			END
		END
		ELSE IF @SCHEDULE_ENABLED = 1
		BEGIN
			IF (@run_date_outcome IS NULL) OR (@run_date IS NOT NULL /*AND @curr_time_last_run_is_valid = 0*/)
				IF(@CALCULATED_DATE IS NOT NULL)
				BEGIN
					SET @current_job_state = 1--'Error'
					SET @current_job_description = 4--'Job never run but job schedule order to run'
				END
				ELSE
				BEGIN
					SET @current_job_state = 2--'Warning'
					SET @current_job_description = 5--'Job never run'
				END
			ELSE
			BEGIN
				IF (@CALCULATED_DATE IS NULL) AND ((@run_date_outcome IS NULL)  OR (@run_date IS NOT NULL /*AND  @curr_time_last_run_is_valid = 0*/))
				BEGIN
					SET @current_job_state = 2--'Warning'
					SET @current_job_description = 6--'Possibly Job expired, please, check configuration of job scheduler'
				END
				ELSE
				BEGIN

					DECLARE @last_outcome_is_according_schedule bit 
					SET @last_outcome_is_according_schedule = 0;
					IF (@run_date_outcome IS NOT NULL) AND (@CALCULATED_DATE IS NOT NULL)
						IF ABS(datediff(MINUTE, @run_date_outcome,@CALCULATED_DATE)) <=  @estimated_job_duration
							SET @last_outcome_is_according_schedule = 1

					IF @last_outcome_is_according_schedule = 1
					BEGIN
						SET @current_job_state =	CASE @run_status_outcome
														WHEN 1 THEN 3--'Healhy' 
														WHEN 3 THEN 3--'Healhy' (Job was cancelled)
														WHEN 0 THEN 1--'Error'
														ELSE 4--'Unknown' 
													END
						SET  @current_job_description =	CASE @run_status_outcome
														WHEN 1 THEN 7--'Job is successfully done according to the schedule'
														WHEN 3 THEN 7--'Job is successfully done according to the schedule' (but was cancelled)
														WHEN 0 THEN 1--'Job failed'
														ELSE 11--'Unknown' 
													END
					END
					ELSE
					BEGIN
						
						DECLARE @first_step_begin_date datetime;
						DECLARE @last_job_execution_end_date datetime

						IF  @run_date_outcome IS NOT NULL AND  @run_duration_outcome IS NOT NULL
							SET @last_job_execution_end_date = dateadd(second,@run_duration_outcome,@run_date_outcome)

						SET @first_step_begin_date  =(
							SELECT TOP 1
								msdb.dbo.agent_datetime(run_date, run_time)
							FROM msdb.dbo.sysjobhistory
							WHERE msdb.dbo.agent_datetime(run_date, run_time) > @last_job_execution_end_date
							ORDER BY run_date, run_time
						)

						--process jobs in progress
						IF (@run_date IS NOT NULL) AND (@run_date > @CALCULATED_DATE) /*AND (@curr_time_last_run_is_valid = 1)*/
						BEGIN
							
							DECLARE @can_use_last_outcome_status bit 
							SET @can_use_last_outcome_status = 0
							IF @first_step_begin_date IS NOT NULL AND @run_end_date IS NOT NULL
								IF abs(datediff(minute,@first_step_begin_date,@run_end_date)) <= @estimated_job_duration
									SET @can_use_last_outcome_status = 1
							
							IF @can_use_last_outcome_status = 1 AND @run_status_outcome IS NOT NULL
							BEGIN
								--state will be correct ONLY if previous outcome executed according to the schedule
								SET @current_job_state =	CASE @run_status_outcome
																WHEN 1 THEN 3--'Healhy' 
																WHEN 3 THEN 2--'Warning' (Job was cancelled)
																WHEN 0 THEN 1--'Error'
																ELSE 4--'Unknown' 
															END
								SET  @current_job_description =	CASE @run_status_outcome
																WHEN 1 THEN 17--'Last job execution succeeded'
																WHEN 3 THEN 18--'Last job execution was stopped'
																WHEN 0 THEN 19--'Last job execution failed'
																ELSE 11--'Unknown' 
															END
							END
							ELSE
							BEGIN
								SET @current_job_state =	CASE @run_status
																WHEN 2 THEN 2--'Warning'
																ELSE 3--'Healhy'
															END
								SET @current_job_description = CASE @run_status
																WHEN 2 THEN 10--'Job is retry' 
																ELSE 2--'Job is running' 
															END
							END
						END
						ELSE
						BEGIN
							SET @current_job_state =	CASE @run_status_outcome
															WHEN 0 THEN 1--'Error'
															WHEN 1 THEN 2--'Warning'
															WHEN 3 THEN 2--'Warning'
															ELSE 4--'Unknown'
														END
							SET @current_job_description =	CASE @run_status_outcome
																WHEN 0 THEN 13--'Job is failed and last run time less than presume the schedule'
																WHEN 1 THEN 8--'Job is successfully done but last run time less than presume the schedule'
																WHEN 3 THEN 14--'Job was cancelled and last run time less than presume the schedule'
																ELSE 11--'Unknown' 
															END
						END
					END
				END
			END
		END
	END

INSERT INTO @Results 
SELECT
	@current_job_state AS [State]
	,@current_job_description AS Description
	,@job_id AS JobId
	,@JOB_NAME AS JobName
	,@JOB_LOCATION AS JobLocation
	,@ID AS Guid;

SELECT * FROM @Results;



--GetSecurablesServerConfig
DECLARE @xmlDoc XML = CAST(@SecurableConfigXml AS XML);

DECLARE @TargetSecurables TABLE(
	[Name] NVARCHAR(128)
	,[PermissionType] NVARCHAR(30)
	,[SecurableType] INT
	,[SqlCondition] INT
);

INSERT INTO @TargetSecurables
SELECT 
	xc.value('./name[1]', 'NVARCHAR(128)') AS [Name]
	,xc.value('./pt[1]', 'NVARCHAR(30)') AS [PermissionType]
	,xc.value('./st[1]', 'INT') AS [SecurableType]
	,xc.value('./cn[1]', 'INT') AS [SqlCondition]
FROM @xmlDoc.nodes('/*/dmv') AS xt(xc);

DECLARE @IsHadrEnabled INT = CAST(SERVERPROPERTY('IsHadrEnabled') AS INT);

WITH src AS(
	SELECT
		tObj.[Name]
		,tObj.SecurableType
		,CASE tObj.SecurableType
			WHEN 0 THEN HAS_PERMS_BY_NAME(NULL, NULL, tObj.[Name])
			ELSE HAS_PERMS_BY_NAME(tObj.[Name], 'OBJECT', tObj.PermissionType)
		END AS HasPermission
	FROM @TargetSecurables tObj
	WHERE tObj.SqlCondition = 0 OR (tObj.SqlCondition = 1 AND @IsHadrEnabled = 1)
)
SELECT
	src.[Name] AS [Name]
	,SecurableType AS [SecurableType]
FROM src
WHERE src.HasPermission = 0;




--SubscriptionPendingCmdQuery
DECLARE @query NVARCHAR(max);

SET @query = N'
DECLARE @replication_servers TABLE (
	server_id INT NOT NULL
	,[name] SYSNAME NOT NULL
	,[data_source] NVARCHAR(4000)
	);
DECLARE @data TABLE (
	Publisher NVARCHAR(4000)
	,Subscriber NVARCHAR(4000)
	,PublisherDb SYSNAME
	,SubscriberDb SYSNAME
	,Publication SYSNAME
	,PendingCmdCount INT NULL
	);
DECLARE @temp TABLE (pendingcmdcount INT NULL);
DECLARE @agent_id INT
	,@xact_seqno VARBINARY(16)
	,@subscriber_db SYSNAME
	,@publisher_db SYSNAME
	,@publication SYSNAME
	,@publisher NVARCHAR(4000)
	,@subscriber NVARCHAR(4000)
	,@pendingcmdcount INT;

DECLARE @in_subscriber NVARCHAR(4000) = ' + QUOTENAME(@subscriber, '''') + ';';

SELECT @query = @query + N'

USE ' + QUOTENAME([name]) + N';

DELETE
FROM @replication_servers;

IF OBJECT_ID(N''dbo.MSreplservers'') IS NOT NULL
	INSERT INTO @replication_servers
	SELECT srvid
		,srvname
		,[data_source]
	FROM dbo.MSreplservers AS r
	INNER JOIN [master].sys.servers AS s ON s.[name] = r.srvname COLLATE SQL_Latin1_General_CP1_CI_AS;
ELSE
	INSERT INTO @replication_servers
	SELECT server_id
		,[name]
		,[data_source]
	FROM [master].sys.servers;

DECLARE INFO_CURSOR CURSOR
FOR
SELECT a.id
	,ISNULL(h.xact_seqno, 0x0)
	,p.[data_source]
	,s.[data_source]
	,a.publication
	,a.publisher_db
	,a.subscriber_db
FROM dbo.MSdistribution_agents a
JOIN dbo.MSdistribution_history h ON a.id = h.agent_id
LEFT JOIN @replication_servers p ON p.server_id = a.publisher_id
LEFT JOIN @replication_servers s ON s.server_id = a.subscriber_id
WHERE s.[data_source] = @in_subscriber COLLATE SQL_Latin1_General_CP1_CI_AS
	AND a.subscriber_id > - 1
	AND h.[timestamp] = (
		SELECT MAX(mts)
		FROM (
			SELECT MAX([timestamp]) mts
			FROM dbo.MSdistribution_history
			WHERE agent_id = a.id
				AND runstatus IN (2, 3, 4)
			GROUP BY start_time
			) AS T
		)

OPEN INFO_CURSOR;

FETCH NEXT
FROM INFO_CURSOR
INTO @agent_id
	,@xact_seqno
	,@publisher
	,@subscriber
	,@publication
	,@publisher_db
	,@subscriber_db;

WHILE @@FETCH_STATUS = 0
BEGIN
	INSERT INTO @temp
	EXEC dbo.sp_MSget_repl_commands @agent_id = @agent_id
		,@last_xact_seqno = @xact_seqno
		,@get_count = 2
		,@compatibility_level = 9000000;

	SELECT @pendingcmdcount = pendingcmdcount
	FROM @temp;

	DELETE
	FROM @temp;

	INSERT INTO @data
	VALUES (
		@publisher
		,@in_subscriber
		,@publisher_db
		,@subscriber_db
		,@publication
		,@pendingcmdcount
		);

	FETCH NEXT
	FROM INFO_CURSOR
	INTO @agent_id
		,@xact_seqno
		,@publisher
		,@subscriber
		,@publication
		,@publisher_db
		,@subscriber_db;
END

CLOSE INFO_CURSOR;

DEALLOCATE INFO_CURSOR;'
FROM [master].sys.databases
WHERE is_distributor = 1;

SET @query = @query + N'

SELECT *
FROM @data;';

EXEC (@query);



--DistributorFindSubscriptionsWithAgents
DECLARE @query NVARCHAR(max);

SET @query = N'
DECLARE @agents TABLE (
	Subscriber NVARCHAR(4000)
	,SubscriberDb SYSNAME
	,Publisher NVARCHAR(4000)
	,PublisherDb SYSNAME
	,PublicationName SYSNAME
	,AgentCategory NVARCHAR(20)
	,DistributionDb SYSNAME
	,Guid UNIQUEIDENTIFIER
	);
DECLARE @replication_servers TABLE (
	server_id INT NOT NULL
	,[name] SYSNAME NOT NULL
	,[data_source] NVARCHAR(4000)
	);';

SELECT @query = @query + N'

USE ' + QUOTENAME([name]) + N';

DELETE
FROM @replication_servers;

IF OBJECT_ID(N''dbo.MSreplservers'') IS NOT NULL
	INSERT INTO @replication_servers
	SELECT srvid
		,srvname
		,[data_source]
	FROM dbo.MSreplservers AS r
	INNER JOIN [master].sys.servers AS s ON s.[name] = r.srvname COLLATE SQL_Latin1_General_CP1_CI_AS;
ELSE
	INSERT INTO @replication_servers
	SELECT server_id
		,[name]
		,[data_source]
	FROM [master].sys.servers;

INSERT INTO @agents
SELECT s.[data_source] AS [Subscriber]
	,a.subscriber_db AS [SubscriberDb]
	,p.[data_source] AS [Publisher]
	,a.publisher_db AS [PublisherDb]
	,a.[publication] AS [PublicationName]
	,''Distribution'' AS [AgentCategory]
	,DB_NAME() AS [DistributionDb]
	,NEWID() AS [Guid]
FROM dbo.MSdistribution_agents a
INNER JOIN @replication_servers s ON a.subscriber_id = s.server_id
INNER JOIN @replication_servers p ON a.publisher_id = p.server_id
WHERE a.local_job = 0;

INSERT INTO @agents
SELECT s.[data_source] AS [Subscriber]
	,a.subscriber_db AS [SubscriberDb]
	,p.[data_source] AS [Publisher]
	,a.publisher_db AS [PublisherDb]
	,a.[publication] AS [PublicationName]
	,''Merge'' AS [AgentCategory]
	,DB_NAME() AS [DistributionDb]
	,NEWID() AS [Guid]
FROM dbo.MSmerge_agents a
INNER JOIN @replication_servers s ON a.subscriber_id = s.server_id
INNER JOIN @replication_servers p ON a.publisher_id = p.server_id
WHERE a.local_job = 0;'
FROM [master].sys.databases
WHERE is_distributor = 1;

SET @query = @query + N'

SELECT *
FROM @agents;';

EXEC (@query);




--GetAgentServiceStatus
SELECT 
	startup_type AS [StartupType]
	,[status] AS [Status]
FROM sys.dm_server_services 
WHERE [filename] LIKE '"%\Binn\SQLAGENT.EXE" -i%'



--ReplicationAgentsStateQuery
DECLARE @query NVARCHAR(max);

SET @query = N'
DECLARE @replication_servers TABLE (
	server_id INT NOT NULL
	,[name] SYSNAME NOT NULL
	,[data_source] NVARCHAR(4000)
	);
DECLARE @data TABLE (
	job_id UNIQUEIDENTIFIER
	,job_name NVARCHAR(MAX)
	,job_location NVARCHAR(MAX)
	,distributor SYSNAME
	,distribution_db SYSNAME
	,publiher NVARCHAR(MAX)
	,publication_db NVARCHAR(MAX)
	,subscriber NVARCHAR(MAX)
	,subscription_db NVARCHAR(MAX)
	,publication_name NVARCHAR(MAX)
	,agent_name NVARCHAR(MAX)
	);';

SELECT @query = @query + N'

USE ' + QUOTENAME([name]) + N';

DELETE
FROM @replication_servers;

IF OBJECT_ID(N''dbo.MSreplservers'') IS NOT NULL
	INSERT INTO @replication_servers
	SELECT srvid
		,srvname
		,[data_source]
	FROM dbo.MSreplservers AS r
	INNER JOIN [master].sys.servers AS s ON s.[name] = r.srvname COLLATE SQL_Latin1_General_CP1_CI_AS;
ELSE
	INSERT INTO @replication_servers
	SELECT server_id
		,[name]
		,[data_source]
	FROM [master].sys.servers;

INSERT INTO @data
SELECT a.job_id
	,a.[name]
	,@@SERVERNAME
	,@@SERVERNAME
	,DB_NAME()
	,p.[data_source]
	,ss.publisher_db
	,s.[data_source]
	,ss.subscriber_db
	,pp.publication
	,''Distribution''
FROM dbo.MSdistribution_agents a
LEFT JOIN (
	SELECT publication_id
		,subscriber_id
		,subscriber_db
		,MAX(agent_id) agent_id
		,MAX(publisher_db) publisher_db
		,MAX(publisher_id) publisher_id
	FROM dbo.MSsubscriptions
	GROUP BY publication_id
		,subscriber_id
		,subscriber_db
	) ss ON a.id = ss.agent_id
INNER JOIN dbo.MSpublications pp ON pp.publication_id = ss.publication_id
INNER JOIN @replication_servers p ON p.server_id = ss.publisher_id
LEFT JOIN @replication_servers s ON s.server_id = ss.subscriber_id
INNER JOIN msdb.dbo.sysjobs j ON j.job_id = a.job_id

UNION ALL

SELECT a.job_id
	,a.[name]
	,@@SERVERNAME
	,@@SERVERNAME
	,DB_NAME()
	,p.[data_source]
	,pp.publisher_db
	,NULL
	,NULL
	,pp.publication
	,''Log reader''
FROM dbo.MSpublications pp
INNER JOIN dbo.MSlogreader_agents a ON a.publisher_id = pp.publisher_id
	AND a.publisher_db = pp.publisher_db
	AND pp.publication_type = 0 --Transactional
INNER JOIN @replication_servers p ON p.server_id = pp.publisher_id
INNER JOIN msdb.dbo.sysjobs j ON j.job_id = a.job_id

UNION ALL

SELECT a.job_id
	,a.[name]
	,@@SERVERNAME
	,@@SERVERNAME
	,DB_NAME()
	,NULL
	,NULL
	,NULL
	,NULL
	,NULL
	,''Queue reader''
FROM dbo.MSqreader_agents a
INNER JOIN msdb.dbo.sysjobs j ON j.job_id = a.job_id

UNION ALL

SELECT a.job_id
	,a.[name]
	,@@SERVERNAME
	,@@SERVERNAME
	,DB_NAME()
	,p.[data_source]
	,pp.publisher_db
	,NULL
	,NULL
	,pp.publication
	,''Snapshot''
FROM dbo.MSsnapshot_agents a
INNER JOIN dbo.MSpublications pp ON pp.publisher_id = a.publisher_id
	AND pp.publisher_db = a.publisher_db
	AND pp.publication = a.publication
INNER JOIN @replication_servers p ON p.server_id = pp.publisher_id
INNER JOIN msdb.dbo.sysjobs j ON j.job_id = a.job_id

UNION ALL

SELECT a.job_id
	,a.[name]
	,@@SERVERNAME
	,@@SERVERNAME
	,DB_NAME()
	,p.[data_source]
	,a.publisher_db
	,s.[data_source]
	,a.subscriber_db
	,a.publication
	,''Merge''
FROM dbo.MSmerge_agents a
INNER JOIN @replication_servers p ON p.server_id = a.publisher_id
LEFT JOIN @replication_servers s ON s.server_id = a.subscriber_id
INNER JOIN msdb.dbo.sysjobs j ON j.job_id = a.job_id;'
FROM sys.databases
WHERE is_distributor = 1;

SET @query = @query + N'

SELECT *
FROM @data;';

DECLARE @JOB_LIST TABLE (
	job_id UNIQUEIDENTIFIER
	,job_name NVARCHAR(MAX)
	,job_location NVARCHAR(MAX)
	,distributor SYSNAME
	,distribution_db SYSNAME
	,publiher NVARCHAR(MAX)
	,publication_db NVARCHAR(MAX)
	,subscriber NVARCHAR(MAX)
	,subscription_db NVARCHAR(MAX)
	,publication_name NVARCHAR(MAX)
	,agent_name NVARCHAR(MAX)
	);

INSERT INTO @JOB_LIST exec (@query)


DECLARE @CALCULATED_DATE_LIST TABLE(schedule_id int,
									schedule_uid UNIQUEIDENTIFIER,
									enabled INT,
									CALCULATED_DATE DATETIME);

declare @schedule_id             int;
declare @schedule_uid			 UNIQUEIDENTIFIER;
declare @enabled				 int;
declare @freq_type				 int;
declare @freq_interval			 int;
declare @freq_subday_type		 int;
declare @freq_subday_interval	 int;
declare @freq_relative_interval	 int;
declare @freq_recurrence_factor	 int;
declare @active_start_date		 int;
declare @active_end_date		 int;
declare @active_start_time		 int;
declare @active_end_time		 int;

DECLARE CURRENT_SCHEDULE_CURSOR CURSOR FOR 
SELECT schedule.schedule_id
      ,schedule.schedule_uid
      ,schedule.enabled
      ,schedule.freq_type
      ,schedule.freq_interval
      ,schedule.freq_subday_type
      ,schedule.freq_subday_interval
      ,schedule.freq_relative_interval
      ,schedule.freq_recurrence_factor
      ,schedule.active_start_date
      ,schedule.active_end_date
      ,schedule.active_start_time
      ,schedule.active_end_time
  FROM msdb.dbo.sysschedules schedule
  JOIN  msdb.[dbo].[sysjobschedules] jobschedule ON schedule.schedule_id = jobschedule.schedule_id
  WHERE jobschedule.job_id IN (SELECT DISTINCT job_id FROM @JOB_LIST)
  

OPEN CURRENT_SCHEDULE_CURSOR

FETCH NEXT FROM CURRENT_SCHEDULE_CURSOR 
INTO @schedule_id           ,        
	 @schedule_uid			,
	 @enabled				,
	 @freq_type				,
	 @freq_interval			,
	 @freq_subday_type		,
	 @freq_subday_interval	,
	 @freq_relative_interval,
	 @freq_recurrence_factor,
	 @active_start_date		,
	 @active_end_date		,
	 @active_start_time		,
	 @active_end_time		;

DECLARE @USED_DAYS TABLE ( DAY_NUMBER INT);

DECLARE @START_DATE DATETIME;
DECLARE @END_DATE DATETIME;
DECLARE @NOW DATETIME 
SET @NOW =  GETDATE(); 
DECLARE @CURRENT_DAY INT 
SET @CURRENT_DAY = DATEPART(DW, @NOW); 

declare @PREVIOUS_CALCULATED_DATE DATETIME 
SET @PREVIOUS_CALCULATED_DATE = NULL;
declare @PREVIOUS_CALCULATED_TIME DATETIME 
SET @PREVIOUS_CALCULATED_TIME = NULL;

WHILE @@FETCH_STATUS = 0
BEGIN
	SET @START_DATE =  CAST(@active_start_date	AS varchar(MAX));
	DECLARE @START_SECOND INT 
	SET @START_SECOND = DATEDIFF(second,0,Stuff(Stuff(right('000000'+Cast(@active_start_time as Varchar),6),3,0,':'),6,0,':'));
	SET @START_DATE = DATEADD(SECOND, @START_SECOND, @START_DATE);

	SET @END_DATE =  CAST(@active_end_date	AS varchar(MAX));
	DECLARE @END_SECOND INT 
	SET @END_SECOND = DATEDIFF(second,0,Stuff(Stuff(right('000000'+Cast(@active_end_time as Varchar),6),3,0,':'),6,0,':'));
	SET @END_DATE = DATEADD(SECOND, @END_SECOND, @END_DATE);

	SET @PREVIOUS_CALCULATED_DATE = NULL;

	IF   NOT (@enabled = 0 OR @START_DATE > @NOW OR @END_DATE < @NOW)
	BEGIN
		SET @PREVIOUS_CALCULATED_DATE = @START_DATE;
		
		IF @freq_type = 4  OR --Daily
		   @freq_type = 8  OR -- Weekly
		   @freq_type = 16  OR -- Monthly
		   @freq_type = 32   -- Monthly, relative to freq_interval
		BEGIN
			-- GLOBAL VARS
			DECLARE @ITER_DATE DATETIME 
			SET @ITER_DATE = @START_DATE;
			DECLARE @ITERATOR INT 
			SET @ITERATOR = 0;
			DECLARE @DAY_COUNTER INT 
			SET @DAY_COUNTER = 0;
			DECLARE @WEEK_COUNTER INT  
			SET @WEEK_COUNTER = 0;
			DECLARE @MONTH_COUNTER INT 
			SET @MONTH_COUNTER = 0;

			IF @freq_type = 4  --Daily
			BEGIN
				SET @DAY_COUNTER = 0;
				WHILE @ITER_DATE < @NOW
					BEGIN
						IF (@DAY_COUNTER % @freq_interval) = 0
							SET @PREVIOUS_CALCULATED_DATE = @ITER_DATE;
						SET @DAY_COUNTER = @DAY_COUNTER + 1; 
						SET @ITER_DATE = DATEADD(DAY, 1, @ITER_DATE);
					END
			END

			IF @freq_type = 8  -- Weekly
			BEGIN
				SET @ITERATOR = 1;
				-- FIND USED DAY OF WEEK
				WHILE @ITERATOR <= 7
					BEGIN
						DECLARE @DEGREE_OF_TWO INT 
						SET @DEGREE_OF_TWO = CAST(POWER(2, @ITERATOR-1) AS INT);
						IF @freq_interval & @DEGREE_OF_TWO = @DEGREE_OF_TWO
							INSERT INTO @USED_DAYS VALUES(@ITERATOR);
						SET @ITERATOR= @ITERATOR + 1;
					END

				-- LOOP ON ALL DAYS FROM START TO NOW AND CHECK IF CONDITION PASSED
				DECLARE @IS_PREVIOUS_RUNS_EXIST BIT 
				SET @IS_PREVIOUS_RUNS_EXIST = 0;
				SET @WEEK_COUNTER  = 0;

				WHILE @ITER_DATE < @NOW
					BEGIN
						IF EXISTS (SELECT * FROM @USED_DAYS WHERE DAY_NUMBER = DATEPART(DW, @ITER_DATE))
							BEGIN
								SET @IS_PREVIOUS_RUNS_EXIST = 1;
								IF (@WEEK_COUNTER % @freq_recurrence_factor) = 0
									SET @PREVIOUS_CALCULATED_DATE = @ITER_DATE; 
							END

						IF @IS_PREVIOUS_RUNS_EXIST = 1 AND DATEPART(DW, @ITER_DATE) = 7
							SET @WEEK_COUNTER = @WEEK_COUNTER + 1;

						SET @ITER_DATE = DATEADD(DAY, 1, @ITER_DATE);
					END
				-- CLEAR TABLE @USED_DAYS
				DELETE FROM @USED_DAYS
			END 

			IF @freq_type = 16  -- Monthly
			BEGIN
				SET @PREVIOUS_CALCULATED_DATE = NULL
				DECLARE @DAYS_IN_MONTH INT;

				IF DATEPART(DAY, @START_DATE) > @freq_interval 
					BEGIN
						SET @ITERATOR = 1;
						-- FIND FIRST RUN
						WHILE @ITERATOR < 3
							BEGIN
								SET @START_DATE = DATEADD(MONTH, 1, @START_DATE);
								SET @DAYS_IN_MONTH  = DAY(DATEADD(DD,-1,DATEADD(MM,DATEDIFF(MM,-1,@START_DATE),0)))
								IF @DAYS_IN_MONTH > @freq_interval
									SET @START_DATE = CAST(DATEPART(YEAR, @START_DATE) AS VARCHAR)+ '-' +CAST(DATEPART(MONTH, @START_DATE) AS VARCHAR)+ '-' +CAST(@freq_interval AS VARCHAR) + ' ' + Stuff(Stuff(right('000000'+Cast(@active_start_time as Varchar),6),3,0,':'),6,0,':');
								SET @ITERATOR = @ITERATOR + 1;
							END
					END
				ELSE	
					SET @START_DATE = CAST(DATEPART(YEAR, @START_DATE) AS VARCHAR)+ '-' +CAST(DATEPART(MONTH, @START_DATE) AS VARCHAR)+ '-' +CAST(@freq_interval AS VARCHAR) + ' ' + Stuff(Stuff(right('000000'+Cast(@active_start_time as Varchar),6),3,0,':'),6,0,':');


				SET @ITER_DATE = @START_DATE

				IF @START_DATE > @NOW
					SET @START_DATE = NULL;

				SET @PREVIOUS_CALCULATED_DATE = @START_DATE;

				SET @MONTH_COUNTER = 0;
				WHILE @ITER_DATE < @NOW
					BEGIN
						SET @DAYS_IN_MONTH  = DAY(DATEADD(DD,-1,DATEADD(MM,DATEDIFF(MM,-1,@ITER_DATE),0)))
						IF (@MONTH_COUNTER % @freq_recurrence_factor) = 0 AND @DAYS_IN_MONTH > @freq_interval
							SET @PREVIOUS_CALCULATED_DATE = @ITER_DATE; 
						SET @MONTH_COUNTER = @MONTH_COUNTER + 1; 
						SET @ITER_DATE = DATEADD(MONTH, 1, @ITER_DATE);
					END
			END

			IF @freq_type = 32   -- Monthly, relative to freq_interval
			BEGIN
				SET @PREVIOUS_CALCULATED_DATE = NULL
				--1 =  Sunday
				--2 =  Monday
				--3 =  Tuesday
				--4 =  Wednesday
				--5 =  Thursday
				--6 =  Friday
				--7 =  Saturday
				--8 =  Day
				--9 =  Weekday
				--10 = Weekend day
				DECLARE @IS_SUNDAY	    BIT 
				SET @IS_SUNDAY = 0;
				DECLARE @IS_MONDAY	    BIT 
				SET @IS_MONDAY = 0;
				DECLARE @IS_TUESDAY	    BIT 
				SET @IS_TUESDAY = 0;
				DECLARE @IS_WEDNESDAY   BIT 
				SET @IS_WEDNESDAY = 0;
				DECLARE @IS_THURSDAY    BIT 
				SET @IS_THURSDAY = 0;
				DECLARE @IS_FRIDAY	    BIT 
				SET @IS_FRIDAY = 0;
				DECLARE @IS_SATURDAY    BIT 
				SET @IS_SATURDAY = 0;
				DECLARE @IS_DAY		    BIT 
				SET @IS_DAY = 0;
				DECLARE @IS_WEEKDAY	    BIT 
				SET @IS_WEEKDAY = 0;
				DECLARE @IS_WEEKEND_DAY BIT 
				SET @IS_WEEKEND_DAY = 0;

				IF @freq_interval = 1
					SET @IS_SUNDAY	    = 1;
				IF @freq_interval = 2
					SET @IS_MONDAY	    = 1;
				IF @freq_interval = 3
					SET @IS_TUESDAY	    = 1;
				IF @freq_interval = 4
					SET @IS_WEDNESDAY   = 1;
				IF @freq_interval = 5
					SET @IS_THURSDAY    = 1;
				IF @freq_interval = 6
					SET @IS_FRIDAY	    = 1;
				IF @freq_interval = 7
					SET @IS_SATURDAY    = 1;
				IF @freq_interval = 8
					SET @IS_DAY		    = 1;
				IF @freq_interval = 9
					SET @IS_WEEKDAY	    = 1;
				IF @freq_interval = 10
					SET @IS_WEEKEND_DAY = 1;


				--1 = First
				--2 = Second
				--4 = Third
				--8 = Fourth
				--16 = Last
				DECLARE @EVERY INT;
				DECLARE @IS_LAST BIT 
				SET @IS_LAST = 0;

				IF @freq_relative_interval = 16
					SET @IS_LAST = 1
				ELSE
					SET @EVERY = CAST(LOG(@freq_relative_interval)/LOG(2) AS INT) + 1;
				
				DECLARE @CURRENT_DAY_COUNTER INT 
				SET @CURRENT_DAY_COUNTER = 0;
				SET @MONTH_COUNTER = 0;
				DECLARE @PREVIOUS_MONTH INT 
				SET @PREVIOUS_MONTH = DATEPART(MONTH, @START_DATE);
				WHILE @ITER_DATE < @NOW
					BEGIN
						IF @IS_SUNDAY = 1 AND DATEPART(DW, @ITER_DATE) = 1
							IF @IS_LAST = 1 AND (@MONTH_COUNTER % @freq_recurrence_factor) = 0 AND (DAY(DATEADD(DD,-1,DATEADD(MM,DATEDIFF(MM,-1,@ITER_DATE),0))) - DATEPART(DAY, @ITER_DATE)) < 7 --IF DAYS TO END OF MONTH < 7
								SET @PREVIOUS_CALCULATED_DATE = @ITER_DATE; 
							ELSE
							BEGIN
								 SET @CURRENT_DAY_COUNTER = @CURRENT_DAY_COUNTER + 1;
								 IF (@MONTH_COUNTER % @freq_recurrence_factor) = 0 AND @CURRENT_DAY_COUNTER = @EVERY
									SET @PREVIOUS_CALCULATED_DATE = @ITER_DATE;
							END

						IF @IS_MONDAY = 1 AND DATEPART(DW, @ITER_DATE) = 2
							IF @IS_LAST = 1 AND (@MONTH_COUNTER % @freq_recurrence_factor) = 0 AND (DAY(DATEADD(DD,-1,DATEADD(MM,DATEDIFF(MM,-1,@ITER_DATE),0))) - DATEPART(DAY, @ITER_DATE)) < 7 --IF DAYS TO END OF MONTH < 7
								SET @PREVIOUS_CALCULATED_DATE = @ITER_DATE; 
							ELSE
							BEGIN
								 SET @CURRENT_DAY_COUNTER = @CURRENT_DAY_COUNTER + 1;
								 IF (@MONTH_COUNTER % @freq_recurrence_factor) = 0 AND @CURRENT_DAY_COUNTER = @EVERY
									SET @PREVIOUS_CALCULATED_DATE = @ITER_DATE;
							END

						IF @IS_TUESDAY = 1 AND DATEPART(DW, @ITER_DATE) = 3
							IF @IS_LAST = 1 AND (@MONTH_COUNTER % @freq_recurrence_factor) = 0 AND (DAY(DATEADD(DD,-1,DATEADD(MM,DATEDIFF(MM,-1,@ITER_DATE),0))) - DATEPART(DAY, @ITER_DATE)) < 7 --IF DAYS TO END OF MONTH < 7
								SET @PREVIOUS_CALCULATED_DATE = @ITER_DATE; 
							ELSE
							BEGIN
								 SET @CURRENT_DAY_COUNTER = @CURRENT_DAY_COUNTER + 1;
								 IF (@MONTH_COUNTER % @freq_recurrence_factor) = 0 AND @CURRENT_DAY_COUNTER = @EVERY
									SET @PREVIOUS_CALCULATED_DATE = @ITER_DATE;
							END

						IF @IS_WEDNESDAY = 1 AND DATEPART(DW, @ITER_DATE) = 4
							IF @IS_LAST = 1  AND (@MONTH_COUNTER % @freq_recurrence_factor) = 0 AND (DAY(DATEADD(DD,-1,DATEADD(MM,DATEDIFF(MM,-1,@ITER_DATE),0))) - DATEPART(DAY, @ITER_DATE)) < 7 --IF DAYS TO END OF MONTH < 7
								SET @PREVIOUS_CALCULATED_DATE = @ITER_DATE; 
							ELSE
							BEGIN
								 SET @CURRENT_DAY_COUNTER = @CURRENT_DAY_COUNTER + 1;
								 IF (@MONTH_COUNTER % @freq_recurrence_factor) = 0 AND @CURRENT_DAY_COUNTER = @EVERY
									SET @PREVIOUS_CALCULATED_DATE = @ITER_DATE;
							END

						IF @IS_THURSDAY = 1 AND DATEPART(DW, @ITER_DATE) = 5
							IF @IS_LAST = 1 AND (@MONTH_COUNTER % @freq_recurrence_factor) = 0 AND (DAY(DATEADD(DD,-1,DATEADD(MM,DATEDIFF(MM,-1,@ITER_DATE),0))) - DATEPART(DAY, @ITER_DATE)) < 7 --IF DAYS TO END OF MONTH < 7
								SET @PREVIOUS_CALCULATED_DATE = @ITER_DATE; 
							ELSE
							BEGIN
								 SET @CURRENT_DAY_COUNTER = @CURRENT_DAY_COUNTER + 1;
								 IF (@MONTH_COUNTER % @freq_recurrence_factor) = 0 AND @CURRENT_DAY_COUNTER = @EVERY
									SET @PREVIOUS_CALCULATED_DATE = @ITER_DATE;
							END

						IF @IS_FRIDAY = 1 AND DATEPART(DW, @ITER_DATE) = 6
							IF @IS_LAST = 1 AND (@MONTH_COUNTER % @freq_recurrence_factor) = 0 AND (DAY(DATEADD(DD,-1,DATEADD(MM,DATEDIFF(MM,-1,@ITER_DATE),0))) - DATEPART(DAY, @ITER_DATE)) < 7 --IF DAYS TO END OF MONTH < 7
								SET @PREVIOUS_CALCULATED_DATE = @ITER_DATE; 
							ELSE
							BEGIN
								 SET @CURRENT_DAY_COUNTER = @CURRENT_DAY_COUNTER + 1;
								 IF (@MONTH_COUNTER % @freq_recurrence_factor) = 0 AND @CURRENT_DAY_COUNTER = @EVERY
									SET @PREVIOUS_CALCULATED_DATE = @ITER_DATE;
							END

						IF @IS_SATURDAY = 1 AND DATEPART(DW, @ITER_DATE) = 7
							IF @IS_LAST = 1 AND (@MONTH_COUNTER % @freq_recurrence_factor) = 0 AND (DAY(DATEADD(DD,-1,DATEADD(MM,DATEDIFF(MM,-1,@ITER_DATE),0))) - DATEPART(DAY, @ITER_DATE)) < 7 --IF DAYS TO END OF MONTH < 7
								SET @PREVIOUS_CALCULATED_DATE = @ITER_DATE; 
							ELSE
							BEGIN
								 SET @CURRENT_DAY_COUNTER = @CURRENT_DAY_COUNTER + 1;
								 IF (@MONTH_COUNTER % @freq_recurrence_factor) = 0 AND @CURRENT_DAY_COUNTER = @EVERY
									SET @PREVIOUS_CALCULATED_DATE = @ITER_DATE;
							END

						IF @IS_DAY = 1 
							IF @IS_LAST = 1 AND (@MONTH_COUNTER % @freq_recurrence_factor) = 0 AND (DAY(DATEADD(DD,-1,DATEADD(MM,DATEDIFF(MM,-1,@ITER_DATE),0))) - DATEPART(DAY, @ITER_DATE))  = 0 --IF LAST DAY OF MONTH 
								SET @PREVIOUS_CALCULATED_DATE = @ITER_DATE; 
							ELSE IF (@MONTH_COUNTER % @freq_recurrence_factor) = 0 AND @EVERY = DATEPART(DAY, @ITER_DATE)
									SET @PREVIOUS_CALCULATED_DATE = @ITER_DATE;
							 
						IF @IS_WEEKDAY = 1 AND 
							(DATEPART(DW, @ITER_DATE) = 2 OR
							 DATEPART(DW, @ITER_DATE) = 3 OR
							 DATEPART(DW, @ITER_DATE) = 4 OR
							 DATEPART(DW, @ITER_DATE) = 5 OR
							 DATEPART(DW, @ITER_DATE) = 6)
							IF @IS_LAST = 1 AND (@MONTH_COUNTER % @freq_recurrence_factor) = 0 AND (DAY(DATEADD(DD,-1,DATEADD(MM,DATEDIFF(MM,-1,@ITER_DATE),0))) - DATEPART(DAY, @ITER_DATE)) < 3 -- CHECK LAST 3 LFY 
								SET @PREVIOUS_CALCULATED_DATE = @ITER_DATE; 
							ELSE
								BEGIN
									 SET @CURRENT_DAY_COUNTER = @CURRENT_DAY_COUNTER + 1;
									 IF (@MONTH_COUNTER % @freq_recurrence_factor) = 0 AND @CURRENT_DAY_COUNTER = @EVERY
										SET @PREVIOUS_CALCULATED_DATE = @ITER_DATE;
								END

						IF @IS_WEEKEND_DAY = 1 AND 
							(DATEPART(DW, @ITER_DATE) = 1 OR
							 DATEPART(DW, @ITER_DATE) = 7)
							IF @IS_LAST = 1 AND (@MONTH_COUNTER % @freq_recurrence_factor) = 0 AND (DAY(DATEADD(DD,-1,DATEADD(MM,DATEDIFF(MM,-1,@ITER_DATE),0))) - DATEPART(DAY, @ITER_DATE)) < 6 --IF DAYS TO END OF MONTH < 7
								SET @PREVIOUS_CALCULATED_DATE = @ITER_DATE; 
							ELSE
								BEGIN
									 SET @CURRENT_DAY_COUNTER = @CURRENT_DAY_COUNTER + 1;
									 IF (@MONTH_COUNTER % @freq_recurrence_factor) = 0 AND @CURRENT_DAY_COUNTER = @EVERY
										SET @PREVIOUS_CALCULATED_DATE = @ITER_DATE;
								END
						
						SET @ITER_DATE = DATEADD(DAY, 1, @ITER_DATE);
						IF @PREVIOUS_MONTH <> DATEPART(MONTH, @ITER_DATE)
							SET @MONTH_COUNTER  = @MONTH_COUNTER + 1;
					END
			END
						
			IF @PREVIOUS_CALCULATED_DATE IS NOT NULL AND @freq_subday_type <> 1 -- ONCE AT DAY
				BEGIN
					DECLARE @MULTIPLIER INT 
					SET @MULTIPLIER = @freq_subday_interval;					
					IF CAST(FLOOR(CAST(@NOW AS FLOAT)) AS DATETIME) = CAST(FLOOR(CAST(@PREVIOUS_CALCULATED_DATE AS FLOAT)) AS DATETIME)
						BEGIN
							DECLARE @NOW_SECONDS INT 
							SET @NOW_SECONDS = DATEDIFF(SECOND, CAST(FLOOR(CAST(@NOW AS FLOAT)) AS DATETIME), @NOW)
							IF @NOW_SECONDS < @END_SECOND
								SET @END_SECOND = @NOW_SECONDS
						END
					IF @freq_subday_type = 4
						SET @MULTIPLIER = @freq_subday_interval*60;
					IF @freq_subday_type = 8
						SET @MULTIPLIER = @freq_subday_interval*3600;
					SET @PREVIOUS_CALCULATED_DATE = DATEADD(SECOND, (@END_SECOND - @START_SECOND)/@MULTIPLIER*@MULTIPLIER, @PREVIOUS_CALCULATED_DATE);

					

						
				END
		END
	END
	
	
	
	INSERT INTO @CALCULATED_DATE_LIST VALUES(@schedule_id, @schedule_uid, @enabled, @PREVIOUS_CALCULATED_DATE);

	FETCH NEXT FROM CURRENT_SCHEDULE_CURSOR 
	INTO @schedule_id           ,        
		 @schedule_uid			,
		 @enabled				,
		 @freq_type				,
		 @freq_interval			,
		 @freq_subday_type		,
		 @freq_subday_interval	,
		 @freq_relative_interval,
		 @freq_recurrence_factor,
		 @active_start_date		,
		 @active_end_date		,
		 @active_start_time		,
		 @active_end_time		;
END
CLOSE CURRENT_SCHEDULE_CURSOR;
DEALLOCATE CURRENT_SCHEDULE_CURSOR;


DECLARE @JobSatusList TABLE(
	job_id uniqueidentifier
	,run_date_outcome datetime
	,run_duration_outcome int
	,run_status_outcome int
	,run_date datetime
	,run_duration int
	,run_status int
)

INSERT INTO @JobSatusList
SELECT
	sjso.job_id
	,sjso.run_date_outcome
	,sjso.run_duration_outcome
	,sjso.run_status_outcome 
	,sja.run_date
	,sja.run_duration
	,sja.run_status
FROM	
	(
		SELECT 
			sjs.job_id
			,CASE 
				WHEN (last_run_date IS NOT NULL AND last_run_time IS NOT NULL) AND (last_run_date <> 0) THEN msdb.dbo.agent_datetime(last_run_date,last_run_time)
				ELSE NULL
			END run_date_outcome
			,(CASE
			--hours, minutes and seconds
				WHEN LEN(last_run_duration) > 4 THEN CONVERT(VARCHAR(4),LEFT(last_run_duration,LEN(last_run_duration)-4)) * 3600
				+ LEFT(RIGHT(last_run_duration,4),2) * 60 + RIGHT(last_run_duration,2)
				--minutes and seconds
				WHEN LEN(last_run_duration) = 4 THEN LEFT(last_run_duration,2) * 60 + RIGHT(last_run_duration,2)
				WHEN LEN(last_run_duration) = 3 THEN LEFT(last_run_duration,1) * 60 + RIGHT(last_run_duration,2)
				ELSE --only seconds    
					RIGHT(last_run_duration,2) 
				END) run_duration_outcome
			,sjs.last_run_outcome run_status_outcome
		FROM msdb.dbo.sysjobservers sjs
		WHERE last_run_duration is not null
	) sjso
	OUTER APPLY
	(
		SELECT TOP 1
			msdb.dbo.agent_datetime(sjh.run_date, sjh.run_time) run_date
			,(CASE
			--hours, minutes and seconds
				WHEN LEN(run_duration) > 4 THEN CONVERT(VARCHAR(4),LEFT(run_duration,LEN(run_duration)-4)) * 3600
				+ LEFT(RIGHT(run_duration,4),2) * 60 + RIGHT(run_duration,2)
				--minutes and seconds
				WHEN LEN(run_duration) = 4 THEN LEFT(run_duration,2) * 60 + RIGHT(run_duration,2)
				WHEN LEN(run_duration) = 3 THEN LEFT(run_duration,1) * 60 + RIGHT(run_duration,2)
				ELSE --only seconds    
					RIGHT(run_duration,2) 
				END) run_duration
				,sjh.run_status
		FROM msdb.dbo.sysjobhistory sjh
		WHERE sjh.job_id = sjso.job_id
			AND (sjso.run_date_outcome IS NULL OR msdb.dbo.agent_datetime(sjh.run_date, sjh.run_time) > dateadd(SECOND, sjso.run_duration_outcome, sjso.run_date_outcome))
			
		ORDER BY sjh.run_date desc, run_time desc, run_duration desc
	) sja

DECLARE @Continuous_Job_Id_List TABLE(job_id uniqueidentifier)

INSERT INTO @Continuous_Job_Id_List
SELECT
	DISTINCT(sjs.job_id)
FROM msdb.dbo.sysjobschedules sjs
JOIN msdb.dbo.sysschedules ss ON ss.schedule_id = sjs.schedule_id
WHERE ss.enabled = 1 AND ss.freq_type = 64	

DECLARE @XpJobList TABLE (
job_id                UNIQUEIDENTIFIER NOT NULL,
last_run_date         INT              NOT NULL,
last_run_time         INT              NOT NULL,
next_run_date         INT              NOT NULL,
next_run_time         INT              NOT NULL,
next_run_schedule_id  INT              NOT NULL,
requested_to_run      INT              NOT NULL, -- BOOL
request_source        INT              NOT NULL,
request_source_id     sysname          COLLATE database_default NULL,
running               INT              NOT NULL, -- BOOL
current_step          INT              NOT NULL,
current_retry_attempt INT              NOT NULL,
job_state             INT              NOT NULL
)

DECLARE @can_see_all_running_jobs INT
DECLARE @job_owner   sysname

SELECT @can_see_all_running_jobs = ISNULL(IS_SRVROLEMEMBER(N'sysadmin'), 0)
IF (@can_see_all_running_jobs = 0)
BEGIN
	declare @table_role table (rolecount	int null);
	declare @query_role nvarchar(max)
	set @query_role = 'USE msdb; ' + 
		'SELECT ISNULL(IS_MEMBER(N''SQLAgentReaderRole''), 0)'
	insert into @table_role exec (@query_role) 
		
	SELECT @can_see_all_running_jobs = rolecount from @table_role 
END
SELECT @job_owner = SUSER_SNAME()

IF (SELECT value from sys.configurations where name = 'Agent XPs') = 1
BEGIN
	INSERT INTO @XpJobList
	EXECUTE master.dbo.xp_sqlagent_enum_jobs @can_see_all_running_jobs, @job_owner
END

DECLARE @Job_State_Output TABLE(
	[State] int
	,[Description] int
	,JobId uniqueidentifier
	,JobName nvarchar(max)
	,JobLocation nvarchar(max)
	,Distributor sysname
	,DistributionDb sysname
	,Publisher nvarchar(max)
	,PublicationDb nvarchar(max)
	,Subscriber nvarchar(max)
	,SubscriptionDb nvarchar(max)
	,PublicationName nvarchar(max)
	,AgentName nvarchar(max)
)

DECLARE @job_id uniqueidentifier
DECLARE @job_name nvarchar(max)
DECLARE @agent_name nvarchar(max)
DECLARE @SCHEDULE_ENABLED int
DECLARE @JOB_ENABLED int
DECLARE @job_location nVARCHAR(MAX)
DECLARE @distributor SYSNAME
DECLARE @distribution_db sysname
DECLARE @publiher nVARCHAR(MAX)
DECLARE @publication_name nVARCHAR(MAX)
DECLARE @publication_db nVARCHAR(MAX)
DECLARE @subscriber nVARCHAR(MAX)
DECLARE @subscription_db nVARCHAR(MAX)
DECLARE @run_date_outcome datetime
DECLARE @run_duration_outcome int
DECLARE @run_status_outcome int
DECLARE @run_date datetime
DECLARE @run_duration int
DECLARE @run_end_date datetime
DECLARE @run_status int
DECLARE @CALCULATED_DATE datetime
DECLARE @job_is_continuous int

DECLARE @xp_job_state int
DECLARE @xp_running int
DECLARE @xp_current_step int
DECLARE @xp_current_retry_attempt int


DECLARE @current_job_state int
DECLARE @current_job_description int

DECLARE @current_date datetime 
SET @current_date = GETDATE()

DECLARE job_state_source CURSOR FOR 
SELECT DISTINCT
		JL.job_id
		,JL.job_name
		,JL.agent_name
		,JS.enabled SCHEDULE_ENABLED
		,jobs.enabled JOB_ENABLED
		,JL.job_location
		,JL.distributor
		,JL.distribution_db
		,JL.publiher
		,JL.publication_name
		,JL.publication_db
		,JL.subscriber
		,JL.subscription_db
		,jsl.run_date_outcome
		,jsl.run_duration_outcome
		,jsl.run_status_outcome
		,jsl.run_date
		,jsl.run_duration
		,CASE
			WHEN jsl.run_date IS NOT NULL AND jsl.run_duration IS NOT NULL THEN dateadd(second,jsl.run_duration,jsl.run_date)
			ELSE NULL
		END run_end_date
		,jsl.run_status
		,JS.CALCULATED_DATE
		,CASE
			when cj.Continuous is not null then 1
			else 0
		END job_is_continuous
		,xpjl.job_state xp_job_state
		,xpjl.running xp_running
		,xpjl.current_step xp_current_step
		,xpjl.current_retry_attempt xp_current_retry_attempt
		FROM @JOB_LIST JL
		LEFT JOIN (SELECT JS.job_id,MAX(enabled) enabled, MAX(CALCULATED_DATE) CALCULATED_DATE 
			FROM msdb.[dbo].[sysjobschedules] JS 
			JOIN @CALCULATED_DATE_LIST LIST ON LIST.schedule_id = JS.schedule_id
			GROUP BY JS.job_id) JS ON JL.job_id = JS.job_id
		LEFT JOIN msdb.[dbo].[sysjobs] jobs ON JL.job_id = jobs.job_id
		LEFT JOIN msdb.dbo.sysjobservers jobservers ON JL.job_id = jobservers.job_id
		LEFT JOIN @JobSatusList jsl ON JL.job_id = jsl.job_id
		JOIN @XpJobList xpjl ON JL.job_id = xpjl.job_id
		OUTER APPLY (SELECT 1 AS Continuous FROM @Continuous_Job_Id_List jil WHERE jil.job_id = JL.job_id) cj

OPEN job_state_source

FETCH NEXT FROM job_state_source 
INTO 
	@job_id,
	@job_name,
	@agent_name,
	@SCHEDULE_ENABLED,
	@JOB_ENABLED,
	@job_location,
	@distributor,
	@distribution_db,
	@publiher,
	@publication_name,
	@publication_db,
	@subscriber,
	@subscription_db,
	@run_date_outcome,
	@run_duration_outcome,
	@run_status_outcome,
	@run_date,
	@run_duration,
	@run_end_date,
	@run_status,
	@CALCULATED_DATE,
	@job_is_continuous,
	@xp_job_state,
	@xp_running,
	@xp_current_step,
	@xp_current_retry_attempt;


WHILE @@FETCH_STATUS = 0
BEGIN
	
	SET @current_job_state = 4--'Unknown'
	SET @current_job_description = 11--'Unknown' 

	IF @JOB_ENABLED = 0 
	BEGIN
		SET @current_job_state = 2--'Warning'
		SET @current_job_description = 3--'Job is disabled'
	END
	ELSE IF  @SCHEDULE_ENABLED = 0 AND @JOB_ENABLED = 1
	BEGIN
		SET @current_job_state = 2--'Warning'
		SET @current_job_description = 12--'Job is enabled but schedule is disabled'
	END
	ELSE IF @job_is_continuous = 1
	BEGIN
		IF @xp_running = 0 --continuous job is stopped
		BEGIN
			IF @agent_name != 'Snapshot'
			BEGIN
				SET @current_job_state =	CASE @run_status_outcome
												WHEN 0 THEN 1--'Error'
												ELSE 2--'Warning'
											END
				SET @current_job_description =	CASE @run_status_outcome
													WHEN 0 THEN 1--'Job Failed'
													ELSE 15--'Agent is not running'
												END 
			END
			ELSE
			BEGIN
				SET @current_job_state =	CASE @run_status_outcome
												WHEN 1 THEN 3--'Healthy'
												WHEN 0 THEN 1--'Error'
												ELSE 3--'Healthy'
											END
				SET @current_job_description =	CASE @run_status_outcome
													WHEN 1 THEN 2--'Job is running'
													WHEN 0 THEN 1--'Job failed'
													ELSE 2--'Job is running'
												END
			END
		END
		ELSE
		BEGIN
			IF @xp_job_state = 3
			BEGIN
				SET @current_job_state = 2--'Warning' 
				SET @current_job_description = 10--'Job is retry'
			END
			ELSE
			BEGIN
				SET @current_job_state = 3--'Healhy' 
				SET @current_job_description = 2--'Job is running'
			END
		END
	END
	--end of continuous job processing
	ELSE
	BEGIN
		--DECLARE @curr_time_last_run_is_valid bit
		--SET @curr_time_last_run_is_valid = 0
		--IF @run_end_date IS NOT NULL
		--	IF ABS(datediff(MINUTE,@run_end_date,@current_date)) <= @estimated_job_duration
		--		SET @curr_time_last_run_is_valid = 1

		IF @SCHEDULE_ENABLED IS NULL
		BEGIN
			IF (@run_status_outcome IS NULL) AND (@CALCULATED_DATE IS NULL) AND @run_date IS NULL 
			BEGIN
				SET @current_job_state = 2--'Warning'
				SET @current_job_description = 9--'Job exist but never run and has not shcedule'
			END
		END
		ELSE IF @SCHEDULE_ENABLED = 1
		BEGIN
			IF (@run_date_outcome IS NULL) AND (@run_date IS NULL)
				IF(@CALCULATED_DATE IS NOT NULL)
				BEGIN
					SET @current_job_state = 1--'Error'
					SET @current_job_description = 4--'Job never run but job schedule order to run'
				END
				ELSE
				BEGIN
					SET @current_job_state = 2--'Warning'
					SET @current_job_description = 5--'Job never run'
				END
			ELSE
			BEGIN
				IF (@CALCULATED_DATE IS NULL) AND (@run_date_outcome IS NULL) AND (@run_date IS NULL)
				BEGIN
					SET @current_job_state = 2--'Warning'
					SET @current_job_description = 6--'Possibly Job expired, please, check configuration of job scheduler'
				END
				ELSE
				BEGIN

					DECLARE @last_outcome_is_according_schedule bit 
					SET @last_outcome_is_according_schedule = 0;
					IF (@run_date_outcome IS NOT NULL) AND (@CALCULATED_DATE IS NOT NULL)
						IF ABS(datediff(MINUTE, @run_date_outcome,@CALCULATED_DATE)) <=  @estimated_job_duration
							SET @last_outcome_is_according_schedule = 1

					IF @last_outcome_is_according_schedule = 1
					BEGIN
						SET @current_job_state =	CASE @run_status_outcome
														WHEN 1 THEN 3--'Healhy' 
														WHEN 3 THEN 3--'Healhy' (Job was cancelled)
														WHEN 0 THEN 1--'Error'
														ELSE 4--'Unknown' 
													END
						SET  @current_job_description =	CASE @run_status_outcome
														WHEN 1 THEN 7--'Job is successfuly done according to the schedule'
														WHEN 3 THEN 7--'Job is successfuly done according to the schedule' (but was cancelled)
														WHEN 0 THEN 1--'Job failed'
														ELSE 11--'Unknown' 
													END
					END
					ELSE
					BEGIN
						
						DECLARE @first_step_begin_date datetime;
						DECLARE @last_job_execution_end_date datetime

						IF  @run_date_outcome IS NOT NULL AND  @run_duration_outcome IS NOT NULL
							SET @last_job_execution_end_date = dateadd(second,@run_duration_outcome,@run_date_outcome)

						SET @first_step_begin_date  =(
							SELECT TOP 1
								msdb.dbo.agent_datetime(run_date, run_time)
							FROM msdb.dbo.sysjobhistory
							WHERE msdb.dbo.agent_datetime(run_date, run_time) > @last_job_execution_end_date
							ORDER BY run_date, run_time
						)

						--process jobs in progress
						IF (@run_date IS NOT NULL) AND (@run_date > @CALCULATED_DATE) /*AND (@curr_time_last_run_is_valid = 1)*/
						BEGIN
							
							DECLARE @can_use_last_outcome_status bit 
							SET @can_use_last_outcome_status = 0
							IF @first_step_begin_date IS NOT NULL AND @run_end_date IS NOT NULL
								IF abs(datediff(minute,@first_step_begin_date,@run_end_date)) <= @estimated_job_duration
									SET @can_use_last_outcome_status = 1
							
							IF @can_use_last_outcome_status = 1 AND @run_status_outcome IS NOT NULL
							BEGIN
								--state will be correct ONLY if previous outcome executed according to the schedule
								SET @current_job_state =	CASE @run_status_outcome
																WHEN 1 THEN 3--'Healhy' 
																WHEN 3 THEN 2--'Warning' (Job was cancelled)
																WHEN 0 THEN 1--'Error'
																ELSE 4--'Unknown' 
															END
								SET  @current_job_description =	CASE @run_status_outcome
																WHEN 1 THEN 17--'Last job execution succeeded'
																WHEN 3 THEN 18--'Last job execution was stopped'
																WHEN 0 THEN 19--'Last job execution failed'
																ELSE 11--'Unknown' 
															END
							END
							ELSE
							BEGIN
								SET @current_job_state =	CASE @run_status
																WHEN 2 THEN 2--'Warning'
																ELSE 3--'Healhy'
															END
								SET @current_job_description = CASE @run_status
																WHEN 2 THEN 10--'Job is retry' 
																ELSE 2--'Job is running' 
															END
							END
						END
						ELSE
						BEGIN
							SET @current_job_state =	CASE @run_status_outcome
															WHEN 0 THEN 1--'Error'
															WHEN 1 THEN 2--'Warning'
															WHEN 3 THEN 2--'Warning'
															ELSE 4--'Unknown'
														END
							SET @current_job_description =	CASE @run_status_outcome
																WHEN 0 THEN 13--'Job is failed and last run time less than presume the schedule'
																WHEN 1 THEN 8--'Job is successfuly done but last run time less than presume the schedule'
																WHEN 3 THEN 14--'Job was cancelled and last run time less than presume the schedule'
																ELSE 11--'Unknown' 
															END
						END
					END
				END
			END
		END
	END
		
	INSERT INTO @Job_State_Output
	VALUES(
		@current_job_state
		,@current_job_description
		,@job_id
		,@job_name
		,@job_location
		,@distributor
		,@distribution_db
		,@publiher
		,@publication_db
		,@subscriber
		,@subscription_db
		,@publication_name
		,@agent_name
	)

	FETCH NEXT FROM job_state_source 
	INTO 
		@job_id,
		@job_name,
		@agent_name,
		@SCHEDULE_ENABLED,
		@JOB_ENABLED,
		@job_location,
		@distributor,
		@distribution_db,
		@publiher,
		@publication_name,
		@publication_db,
		@subscriber,
		@subscription_db,
		@run_date_outcome,
		@run_duration_outcome,
		@run_status_outcome,
		@run_date,
		@run_duration,
		@run_end_date,
		@run_status,
		@CALCULATED_DATE,
		@job_is_continuous,
		@xp_job_state,
		@xp_running,
		@xp_current_step,
		@xp_current_retry_attempt;
END

CLOSE job_state_source;
DEALLOCATE job_state_source;

select * from @Job_State_Output



--DistributorFailJobsQuery
DECLARE @sDelimiter VARCHAR(1) 
SET @sDelimiter = ','
DECLARE @sItem nVARCHAR(max)
DECLARE @List TABLE (NAME nVARCHAR(max), IS_POSITIVE bit)

WHILE CHARINDEX(@sDelimiter,@sInputPositiveList,0) <> 0
 BEGIN
	
	 SET @sItem = RTRIM(LTRIM(SUBSTRING(@sInputPositiveList,1,CHARINDEX(@sDelimiter,@sInputPositiveList,0)-1)));
	 SET @sInputPositiveList = RTRIM(LTRIM(SUBSTRING(@sInputPositiveList,CHARINDEX(@sDelimiter,@sInputPositiveList,0)+LEN(@sDelimiter),LEN(@sInputPositiveList))))

	IF LEN(@sItem) > 0
		INSERT INTO @List SELECT @sItem, 1
 END
IF LEN(@sInputPositiveList) > 0
	INSERT INTO @List SELECT @sInputPositiveList, 1 


WHILE CHARINDEX(@sDelimiter,@sInputNegativeList,0) <> 0
 BEGIN
	
	 SET @sItem = RTRIM(LTRIM(SUBSTRING(@sInputNegativeList,1,CHARINDEX(@sDelimiter,@sInputNegativeList,0)-1)));
	 SET @sInputNegativeList = RTRIM(LTRIM(SUBSTRING(@sInputNegativeList,CHARINDEX(@sDelimiter,@sInputNegativeList,0)+LEN(@sDelimiter),LEN(@sInputNegativeList))))

	IF LEN(@sItem) > 0
		INSERT INTO @List SELECT @sItem, 0
 END
IF LEN(@sInputNegativeList) > 0
	INSERT INTO @List SELECT @sInputNegativeList, 0


select JobName, ExecDate from (
	SELECT  
	   max(jobsInfo.name) as JobName
	  ,max(jobsInfo.run_status) RunStatus
	  ,count(jobsInfo.job_id) RunCount
	  ,max(jobsInfo.exec_date) ExecDate
	FROM  (
			SELECT  job.name
					     ,history.job_id
					     ,history.step_id
					     ,history.sql_message_id
					     ,history.sql_severity
					     ,history.run_status
					      
					     ,((SUBSTRING(CAST(history.run_date AS VARCHAR(8)), 5, 2) + '/'
					     + SUBSTRING(CAST(history.run_date AS VARCHAR(8)), 7, 2) + '/'
					     + SUBSTRING(CAST(history.run_date AS VARCHAR(8)), 1, 4) + ' '
					     + SUBSTRING((REPLICATE('0',6-LEN(CAST(history.run_time AS varchar)))
					     + CAST(history.run_time AS VARCHAR)), 1, 2) + ':'
					     + SUBSTRING((REPLICATE('0',6-LEN(CAST(history.run_time AS VARCHAR)))
					     + CAST(history.run_time AS VARCHAR)), 3, 2) + ':'
					     + SUBSTRING((REPLICATE('0',6-LEN(CAST(history.run_time as varchar)))
					     + CAST(history.run_time AS VARCHAR)), 5, 2))) AS exec_date
					     ,history.run_duration
					     ,history.retries_attempted
					     ,history.server
					   FROM msdb.dbo.sysjobs job
					   join msdb.dbo.syscategories cat on cat.category_id = job.category_id
					   CROSS apply ( SELECT top (@n) history.job_id, history.instance_id  FROM msdb.dbo.sysjobhistory history where history.job_id = job.job_id AND step_id = 0 order by run_date desc , run_time desc ) ca
					   join msdb.dbo.sysjobhistory history on ca.instance_id = history.instance_id
					   where 
					   
					   (cat.name      IN(SELECT CASE WHEN NAME LIKE 'REPL-%' THEN NAME ELSE 'REPL-' + NAME END FROM @List where IS_POSITIVE = 1) or (NOT EXISTS(SELECT 1 FROM @List where IS_POSITIVE = 1) AND cat.name LIKE 'REPL-%')) and 
					   cat.name  not IN(SELECT CASE WHEN NAME LIKE 'REPL-%' THEN NAME ELSE 'REPL-' + NAME END FROM @List where IS_POSITIVE = 0) 
				  ) AS jobsInfo
		
		group by jobsInfo.job_id
		) T
	where RunStatus = 0 and RunCount = @n



--DistributorGetAllPublisherWithWorkingDirectory
DECLARE @query NVARCHAR(max);

SET @query = N'
DECLARE @publishers TABLE (
	Publisher NVARCHAR(4000)
	,PublisherDb SYSNAME
	,PublicationName SYSNAME
	,DefaultSnapshotLocation NVARCHAR(255)
	);
DECLARE @replication_servers TABLE (
	server_id INT NOT NULL
	,[name] SYSNAME NOT NULL
	,[data_source] NVARCHAR(4000)
	);';

SELECT @query = @query + N'

USE ' + QUOTENAME([name]) + N';

DELETE
FROM @replication_servers;

IF OBJECT_ID(N''dbo.MSreplservers'') IS NOT NULL
	INSERT INTO @replication_servers
	SELECT srvid
		,srvname
		,[data_source]
	FROM dbo.MSreplservers AS r
	INNER JOIN [master].sys.servers AS s ON s.[name] = r.srvname COLLATE SQL_Latin1_General_CP1_CI_AS;
ELSE
	INSERT INTO @replication_servers
	SELECT server_id
		,[name]
		,[data_source]
	FROM [master].sys.servers;

INSERT INTO @publishers
SELECT p.[data_source] Publisher
	,publisher_db PublisherDb
	,publication PublicationName
	,working_directory DefaultSnapshotLocation
FROM dbo.MSpublications pp
INNER JOIN @replication_servers p ON p.server_id = pp.publisher_id
INNER JOIN [msdb].dbo.MSdistpublishers dp ON p.[data_source] = dp.name COLLATE SQL_Latin1_General_CP1_CI_AS;'
FROM [master].sys.databases
WHERE is_distributor = 1;

SET @query = @query + N'

SELECT *
FROM @publishers;';

EXEC (@query);



--DistributorPendingCmdQuery
DECLARE @query NVARCHAR(max);

SET @query = N'
DECLARE @replication_servers TABLE (
	server_id INT NOT NULL
	,[name] SYSNAME NOT NULL
	,[data_source] NVARCHAR(4000)
	);
DECLARE @data TABLE (
	subscription NVARCHAR(max)
	,subscriber NVARCHAR(4000)
	,pendingcmdcount INT NULL
	);
DECLARE @temp TABLE (pendingcmdcount INT NULL);
DECLARE @agent_id INT
	,@xact_seqno VARBINARY(16)
	,@subscriber_db SYSNAME
	,@publisher_db SYSNAME
	,@publication SYSNAME
	,@publisher NVARCHAR(4000)
	,@subscriber NVARCHAR(4000)
	,@subscription NVARCHAR(max)
	,@publisher_id INT
	,@lastrunts TIMESTAMP
	,@pendingcmdcount INT;';

SELECT @query = @query + N'

USE ' + QUOTENAME([name]) + N';

DELETE
FROM @replication_servers;

IF OBJECT_ID(N''dbo.MSreplservers'') IS NOT NULL
	INSERT INTO @replication_servers
	SELECT srvid
		,srvname
		,[data_source]
	FROM dbo.MSreplservers AS r
	INNER JOIN [master].sys.servers AS s ON s.[name] = r.srvname COLLATE SQL_Latin1_General_CP1_CI_AS;
ELSE
	INSERT INTO @replication_servers
	SELECT server_id
		,[name]
		,[data_source]
	FROM [master].sys.servers;

DECLARE INFO_CURSOR CURSOR
FOR
SELECT a.id
	,isnull(h.xact_seqno, 0x0)
	,p.[data_source]
	,s.[data_source]
	,a.publication
	,a.publisher_db
	,a.subscriber_db
	,a.publisher_id
	,h.[timestamp]
FROM dbo.MSdistribution_agents a
JOIN dbo.MSdistribution_history h ON a.id = h.agent_id
LEFT JOIN @replication_servers p ON p.server_id = a.publisher_id
LEFT JOIN @replication_servers s ON s.server_id = a.subscriber_id
WHERE a.subscriber_id > - 1
	AND h.[timestamp] = (
		SELECT max(mts)
		FROM (
			SELECT max([timestamp]) mts
			FROM dbo.MSdistribution_history
			WHERE agent_id = a.id
				AND runstatus IN (2 ,3 ,4)
			GROUP BY start_time
			) AS T
		)

OPEN INFO_CURSOR;

FETCH NEXT
FROM INFO_CURSOR
INTO @agent_id
	,@xact_seqno
	,@publisher
	,@subscriber
	,@publication
	,@publisher_db
	,@subscriber_db
	,@publisher_id
	,@lastrunts;

WHILE @@FETCH_STATUS = 0
BEGIN
	IF @lastrunts IS NOT NULL
		OR NOT EXISTS (
			SELECT *
			FROM dbo.MSpublications p
			JOIN dbo.MSsubscriptions s ON p.publication_id = s.publication_id
			WHERE p.publisher_id = @publisher_id
				AND p.publisher_db = @publisher_db
				AND p.publication = @publication
				AND p.immediate_sync = 1
				AND s.[status] = 1
				AND s.subscriber_id = - 1
			)
	BEGIN
		INSERT INTO @temp
		EXEC dbo.sp_MSget_repl_commands @agent_id = @agent_id
			,@last_xact_seqno = @xact_seqno
			,@get_count = 2
			,@compatibility_level = 9000000;

		SELECT @pendingcmdcount = pendingcmdcount
		FROM @temp;

		DELETE
		FROM @temp;

		SET @subscription = ''['' + @subscriber_db + ''] - '' + ''['' + @publisher + ''].['' + @publisher_db + '']: '' + @publication;

		INSERT INTO @data
		VALUES (
			@subscription
			,@subscriber
			,@pendingcmdcount
			)
	END

	FETCH NEXT
	FROM INFO_CURSOR
	INTO @agent_id
		,@xact_seqno
		,@publisher
		,@subscriber
		,@publication
		,@publisher_db
		,@subscriber_db
		,@publisher_id
		,@lastrunts;
END

CLOSE INFO_CURSOR;

DEALLOCATE INFO_CURSOR;'
FROM [master].sys.databases
WHERE is_distributor = 1;

SET @query = @query + N'

SELECT *
FROM @data
WHERE pendingcmdcount > 0;';

EXEC (@query);



--DistributorSubscriptionsQuery
declare @ParmDefinition nVARCHAR(40);
declare @CountOfSubscription int;
declare @CountOfWrongSubscription int;
SET @ParmDefinition = N'@CountOfSubscriptionOut int OUTPUT';

declare @query nvarchar(max) 
SET @query = N'';
SELECT @query = @query + N'SELECT  COUNT(*) [COUNTER] from (select [publication_id],[subscriber_id],[subscriber_db] FROM   ' + QUOTENAME(NAME, '"') + '.[dbo].[MSsubscriptions] where subscriber_id > -1 group by [publication_id],[subscriber_id],[subscriber_db]) t UNION ALL '
	FROM sys.databases where is_distributor = 1;
SELECT @query = @query + N'SELECT  COUNT(*) [COUNTER] FROM   ' + QUOTENAME(NAME, '"') + '.[dbo].[MSmerge_subscriptions]  UNION ALL '
	FROM sys.databases where is_distributor = 1;

declare @query_tail int 
SET @query_tail = LEN('UNION ALL')
IF (LEN(@query) > @query_tail)
BEGIN
	SET @query = SUBSTRING ( @query ,0 , LEN(@query) - @query_tail )
	SET @query = N'SELECT @CountOfSubscriptionOut = SUM([COUNTER])   FROM ('+@query+N') T0';
END

EXECUTE sp_executesql @query, @ParmDefinition, @CountOfSubscriptionOut = @CountOfSubscription OUTPUT;

select ISNULL(@CountOfSubscription, 0) DistributorSubscriptionsCount



--SubscriptionLongEstimatedTimeQuery
DECLARE @query NVARCHAR(max);

SET @query = N'
DECLARE @replication_servers TABLE (
	server_id INT NOT NULL
	,[name] SYSNAME NOT NULL
	,[data_source] NVARCHAR(4000)
	);
DECLARE @data TABLE (
	Publisher NVARCHAR(4000)
	,Subscriber NVARCHAR(4000)
	,PublisherDb SYSNAME
	,SubscriberDb SYSNAME
	,Publication SYSNAME
	,EstimatedTime INT NULL
	);
DECLARE @temp TABLE (pendingcmdcount INT NULL);
DECLARE @agent_id INT
	,@xact_seqno VARBINARY(16)
	,@subscriber_db SYSNAME
	,@publisher_db SYSNAME
	,@publication SYSNAME
	,@publisher NVARCHAR(4000)
	,@subscriber NVARCHAR(4000)
	,@delivery_rate float
	,@estimatedprocesstime int
	,@pendingcmdcount INT;

DECLARE @in_subscriber NVARCHAR(4000) = ' + QUOTENAME(@subscriber, '''') + ';';

SELECT @query = @query + N'

USE ' + QUOTENAME([name]) + N';

DELETE
FROM @replication_servers;

IF OBJECT_ID(N''dbo.MSreplservers'') IS NOT NULL
	INSERT INTO @replication_servers
	SELECT srvid
		,srvname
		,[data_source]
	FROM dbo.MSreplservers AS r
	INNER JOIN [master].sys.servers AS s ON s.[name] = r.srvname COLLATE SQL_Latin1_General_CP1_CI_AS;
ELSE
	INSERT INTO @replication_servers
	SELECT server_id
		,[name]
		,[data_source]
	FROM [master].sys.servers;

DECLARE INFO_CURSOR CURSOR
FOR
SELECT a.id
	,ISNULL(h.xact_seqno, 0x0)
	,p.[data_source]
	,s.[data_source]
	,a.publication
	,a.publisher_db
	,a.subscriber_db
	,ISNULL(h.delivery_rate, 0.0)
FROM dbo.MSdistribution_agents a
JOIN dbo.MSdistribution_history h ON a.id = h.agent_id
LEFT JOIN @replication_servers p ON p.server_id = a.publisher_id
LEFT JOIN @replication_servers s ON s.server_id = a.subscriber_id
WHERE s.[data_source] = @in_subscriber COLLATE SQL_Latin1_General_CP1_CI_AS
	AND a.subscriber_id > - 1
	AND h.[timestamp] = (
		SELECT MAX(mts)
		FROM (
			SELECT MAX([timestamp]) mts
			FROM dbo.MSdistribution_history
			WHERE agent_id = a.id
				AND runstatus IN (2, 3, 4)
			GROUP BY start_time
			) AS T
		)

OPEN INFO_CURSOR;

FETCH NEXT
FROM INFO_CURSOR
INTO @agent_id
	,@xact_seqno
	,@publisher
	,@subscriber
	,@publication
	,@publisher_db
	,@subscriber_db
	,@delivery_rate;

WHILE @@FETCH_STATUS = 0
BEGIN
	INSERT INTO @temp
	EXEC dbo.sp_MSget_repl_commands @agent_id = @agent_id
		,@last_xact_seqno = @xact_seqno
		,@get_count = 2
		,@compatibility_level = 9000000;

	SELECT @pendingcmdcount = pendingcmdcount
	FROM @temp;

	DELETE
	FROM @temp;

	IF (@delivery_rate = 0.0)
	BEGIN
		SELECT @delivery_rate = ISNULL(AVG(delivery_rate), 0.0)
		FROM dbo.MSdistribution_history
		WHERE agent_id = @agent_id
	END

	SELECT @estimatedprocesstime = CASE 
			WHEN (@delivery_rate != 0.0)
				THEN CAST((CAST(@pendingcmdcount AS FLOAT) / @delivery_rate) AS INT)
			ELSE @pendingcmdcount
			END

	INSERT INTO @data
	VALUES (
		@publisher
		,@in_subscriber
		,@publisher_db
		,@subscriber_db
		,@publication
		,@estimatedprocesstime
		);

	FETCH NEXT
	FROM INFO_CURSOR
	INTO @agent_id
		,@xact_seqno
		,@publisher
		,@subscriber
		,@publication
		,@publisher_db
		,@subscriber_db
		,@delivery_rate;
END

CLOSE INFO_CURSOR;

DEALLOCATE INFO_CURSOR;'
FROM [master].sys.databases
WHERE is_distributor = 1;

SET @query = @query + N'

SELECT *
FROM @data;';

EXEC (@query);



--DistributorUnsyncSubscriptionsQuery
DECLARE @query NVARCHAR(max);

SET @query = N'
DECLARE @replication_servers TABLE (
	server_id INT NOT NULL
	,[name] SYSNAME NOT NULL
	,[data_source] NVARCHAR(4000)
	);
DECLARE @data TABLE (
	Publisher NVARCHAR(4000)
	,Subscriber NVARCHAR(4000)
	,PublisherDb SYSNAME
	,SubscriberDb SYSNAME
	,Publication SYSNAME
	,PendingCmdCount INT NULL
	);
DECLARE @temp TABLE (pendingcmdcount INT NULL);
DECLARE @agent_id INT
	,@xact_seqno VARBINARY(16)
	,@subscriber_db SYSNAME
	,@publisher_db SYSNAME
	,@publication SYSNAME
	,@publisher NVARCHAR(4000)
	,@subscriber NVARCHAR(4000)
	,@pendingcmdcount INT;

DECLARE @pend_command_limit INT = ' + CAST(@pendingCommandLimit AS NVARCHAR(MAX)) + ';';

SELECT @query = @query + N'

USE ' + QUOTENAME([name]) + N';

DELETE
FROM @replication_servers;

IF OBJECT_ID(N''dbo.MSreplservers'') IS NOT NULL
	INSERT INTO @replication_servers
	SELECT srvid
		,srvname
		,[data_source]
	FROM dbo.MSreplservers AS r
	INNER JOIN [master].sys.servers AS s ON s.[name] = r.srvname COLLATE SQL_Latin1_General_CP1_CI_AS;
ELSE
	INSERT INTO @replication_servers
	SELECT server_id
		,[name]
		,[data_source]
	FROM [master].sys.servers;

DECLARE INFO_CURSOR CURSOR
FOR
SELECT a.id
	,ISNULL(h.xact_seqno, 0x0) AS xact_seqno
	,a.publisher_db
	,a.subscriber_db
	,a.publication
	,p.[data_source] publisher
	,s.[data_source] subscriber
FROM dbo.MSdistribution_agents a
INNER JOIN dbo.MSdistribution_history h ON a.id = h.agent_id
INNER JOIN @replication_servers p ON p.server_id = a.publisher_id
INNER JOIN @replication_servers s ON s.server_id = a.subscriber_id
WHERE h.[timestamp] = (
		SELECT MAX(mts)
		FROM (
			SELECT MAX(timestamp) AS mts
			FROM dbo.MSdistribution_history
			WHERE agent_id = a.id
				AND runstatus IN (2 ,3 ,4)
			GROUP BY start_time
			) AS T
		)

OPEN INFO_CURSOR;

FETCH NEXT
FROM INFO_CURSOR
INTO @agent_id
	,@xact_seqno
	,@publisher_db
	,@subscriber_db
	,@publication
	,@publisher
	,@subscriber;

WHILE @@FETCH_STATUS = 0
BEGIN
	INSERT INTO @temp
	EXEC sp_MSget_repl_commands @agent_id = @agent_id
		,@last_xact_seqno = @xact_seqno
		,@get_count = 2
		,@compatibility_level = 9000000;

	SELECT TOP 1 @pendingcmdcount = pendingcmdcount
	FROM @temp;

	DELETE
	FROM @temp;

	IF (@pendingcmdcount > @pend_command_limit)
		INSERT INTO @data
		VALUES (
			@publisher
			,@subscriber
			,@publisher_db
			,@subscriber_db
			,@publication
			,@pendingcmdcount
			)

	FETCH NEXT
	FROM INFO_CURSOR
	INTO @agent_id
		,@xact_seqno
		,@publisher_db
		,@subscriber_db
		,@publication
		,@publisher
		,@subscriber;
END

CLOSE INFO_CURSOR;

DEALLOCATE INFO_CURSOR;'
FROM [master].sys.databases
WHERE is_distributor = 1;

SET @query = @query + N'

SELECT *
FROM @data;';

EXEC (@query);



--DistributorPercentOfDeactivatedSubscriptionsQuery
DECLARE @query NVARCHAR(max);

SET @query = N'
DECLARE @replication_servers TABLE (
	server_id INT NOT NULL
	,[name] SYSNAME NOT NULL
	,[data_source] NVARCHAR(4000)
	);
DECLARE @data TABLE (
	Publisher NVARCHAR(4000)
	,Subscriber NVARCHAR(4000)
	,Publication SYSNAME
	,PublisherDb SYSNAME
	,SubscriberDb SYSNAME
	,Status TINYINT NOT NULL
	);
DECLARE @total_count INT = 0;

DECLARE @in_status TINYINT = ' + CAST(@status AS NVARCHAR(MAX)) + ';';

SELECT @query = @query + N'

USE ' + QUOTENAME([name]) + N';

DELETE
FROM @replication_servers;

IF OBJECT_ID(N''dbo.MSreplservers'') IS NOT NULL
	INSERT INTO @replication_servers
	SELECT srvid
		,srvname
		,[data_source]
	FROM dbo.MSreplservers AS r
	INNER JOIN [master].sys.servers AS s ON s.[name] = r.srvname COLLATE SQL_Latin1_General_CP1_CI_AS;
ELSE
	INSERT INTO @replication_servers
	SELECT server_id
		,[name]
		,[data_source]
	FROM [master].sys.servers;

SELECT @total_count = @total_count + COUNT(*)
FROM (
	SELECT publication_id
		,subscriber_id
		,subscriber_db
	FROM dbo.MSsubscriptions
	WHERE subscriber_id > - 1
	GROUP BY publication_id
		,subscriber_id
		,subscriber_db
	) t;

INSERT INTO @data
SELECT p.[data_source]
	,s.[data_source]
	,pp.publication
	,pp.publisher_db
	,ss.subscriber_db
	,ss.[status]
FROM (
	SELECT MIN([status]) [status]
		,publication_id
		,subscriber_id
		,subscriber_db
	FROM dbo.MSsubscriptions
	WHERE subscriber_id > - 1
	GROUP BY publication_id
		,subscriber_id
		,subscriber_db
	) ss
INNER JOIN dbo.MSpublications pp ON ss.publication_id = pp.publication_id
LEFT JOIN @replication_servers p ON p.server_id = pp.publisher_id
LEFT JOIN @replication_servers s ON s.server_id = ss.subscriber_id
WHERE [status] = @in_status;'
FROM [master].sys.databases
WHERE is_distributor = 1;

SET @query = @query + N'

SELECT @total_count AS [TotalCount], d.*
FROM @data d;';

EXEC (@query);



--GetInfoFromPublisherQuery
DECLARE @Databases TABLE (
	DatabaseName sysname
)

DECLARE @UnfilteredDatabases TABLE (
	DatabaseName sysname
)

DECLARE @dbname sysname, @sql nvarchar(max), @quotedName nvarchar(max);

INSERT INTO @UnfilteredDatabases
SELECT DISTINCT name as DatabaseName FROM 
(SELECT name FROM sys.databases WHERE is_published = 1 
UNION ALL 
SELECT name FROM sys.databases WHERE is_merge_published = 1) a

Declare temp Cursor LOCAL For 
  Select db.DatabaseName 
	From @UnfilteredDatabases db;
Open temp;

Fetch next From temp into @dbname;

While @@Fetch_Status=0 Begin
	set @quotedName = QUOTENAME(@dbname ,'"')
	set @sql = N'USE '+ @quotedName;
	BEGIN TRY
		EXEC (@sql);
		insert into @Databases values (@dbname);
	END TRY
	BEGIN CATCH
	END CATCH;
	Fetch next From temp into @dbname;
End

Close temp;
Deallocate temp;

declare @query nvarchar(max)

set @query = 'CREATE TABLE #TranPublTemp_GetPublisherInfoQuery  ( ' +
'pubid int, ' +
'name sysname, ' +
'restricted int, ' +
'"status" int, ' +
'task int, ' +
'"replication frequency" int, ' +
'"synchronization method" int, ' +
'"description" nvarchar(max), ' +
'immediate_sync int, ' +
'enabled_for_internet int, ' +
'allow_push int, ' +
'allow_pull int, ' +
'allow_anonymous int, ' +
'independent_agent int, ' +
'immediate_sync_ready int, ' +
'allow_sync_tran int, ' +
'autogen_sync_procs int, ' +
'snapshot_jobid varbinary(255), ' +
'"retention" int, ' +
'"has subscription" int, ' +
'allow_queued_tran int, ' +
'snapshot_in_defaultfolder int, ' +
'alt_snapshot_folder nvarchar(255), ' +
'pre_snapshot_script nvarchar(255), ' +
'post_snapshot_script nvarchar(255), ' +
'compress_snapshot int, ' +
'ftp_address nvarchar(255), ' +
'ftp_port int, ' +
'ftp_subdirectory nvarchar(255), ' +
'ftp_login nvarchar(255), ' +
'allow_dts int, ' +
'allow_subscription_copy int, ' +
'centralized_conflicts int, ' +
'conflict_retention int, ' +
'conflict_policy int, ' +
'queue_type int, ' +
'backward_comp_level int, ' +
'publish_to_AD int, ' +
'allow_initialize_from_backup int, ' +
'replicate_ddl int, ' +
'enabled_for_p2p int, ' +
'publish_local_changes_only int, ' +
'enabled_for_het_sub int, ' +
'enabled_for_p2p_conflictdetection int, ' +
'originator_id int, ' +
'p2p_continue_onconflict int, ' +
'allow_partition_switch int, ' +
'replicate_partition_switch int ' +
'); ' 

set @query = @query + 'CREATE TABLE #MergePublTemp_GetPublisherInfoQuery ( id int, ' +
'name sysname, ' +
'description nvarchar(max), ' +
'"status" int, ' +
'"retention" int, ' +
'sync_mode int, ' +
'allow_push int, ' +
'allow_pull int, ' +
'allow_anonymous int, ' +
'centralized_conflicts int, ' +
'priority int, ' +
'snapshot_ready int, ' +
'publication_type int, ' +
'pubid nvarchar(255), ' +
'snapshot_jobid varbinary(255), ' +
'enabled_for_internet int, ' +
'dynamic_filters int, ' +
'has_subscription int, ' +
'snapshot_in_defaultfolder int, ' +
'alt_snapshot_folder nvarchar(255), ' +
'pre_snapshot_script nvarchar(max), ' +
'post_snapshot_script nvarchar(max), ' +
'compress_snapshot int, ' +
'ftp_address nvarchar(255), ' +
'ftp_port int, ' +
'ftp_subdirectory nvarchar(255), ' +
'ftp_login nvarchar(255), ' +
'conflict_retention int, ' +
'keep_partition_changes int, ' +
'allow_subscription_copy int, ' +
'allow_synctoalternate int, ' +
'validate_subscriber_info int, ' +
'backward_comp_level int, ' +
'publish_to_activedirectory int, ' +
'max_concurrent_merge int, ' +
'max_concurrent_dynamic_snapshots int, ' +
'use_partition_groups int, ' +
'num_of_articles int, ' +
'replicate_ddl int, ' +
'publication_number int, ' +
'allow_subscriber_initiated_snapshot int, ' +
'allow_web_synchronization int, ' +
'web_synchronization_url nvarchar(255), ' +
'allow_partition_realignment int, ' +
'retention_period_unit int, ' +
'has_downloadonly_articles int, ' +
'decentralized_conflicts int, ' +
'generation_leveling_threshold int, ' +
'automatic_reinitialization_policy int ' +
'); '

set @query = @query + 'DECLARE @temp TABLE ( ' +
	'DatabaseName nvarchar(255), ' +
	'PublicationName nvarchar(255), ' +
	'"Description" nvarchar(max), ' +
	'"Type" int, ' +
	'"Retention" int, ' +
	'RetentionInterval int, ' +
	'SynchronizationMethod int, ' +
	'AltSnapshotFolder nvarchar(255), ' +
	'SnapshotInDefaultFolder int ' +
'); ' 

select  @query = @query + 'BEGIN TRY ' +
						  'USE ' + QUOTENAME(DatabaseName, '"') + '; ' +
						  'BEGIN TRY ' +
                          'INSERT INTO #TranPublTemp_GetPublisherInfoQuery EXEC sp_helppublication; ' +
						  'END TRY ' +
						  'BEGIN CATCH ' +
						  -- to support SQL Server 14 sp2+ schema
						  'ALTER TABLE #TranPublTemp_GetPublisherInfoQuery ADD allow_drop int; ' +
                          'INSERT INTO #TranPublTemp_GetPublisherInfoQuery EXEC sp_helppublication; ' +
						  'END CATCH ' +
						  'INSERT INTO #MergePublTemp_GetPublisherInfoQuery EXEC sp_helpmergepublication; ' +
						  'INSERT INTO @temp ' +
						  'SELECT ' + QUOTENAME(DatabaseName, '''') + ' as DatabaseName, ' + 
						  'name as PublicationName, '+
						  '"description" as "Description", '+
						  '"replication frequency" + 1 as "Type", '+
						  '"retention" as "Retention", '+
						  '5 as RetentionInterval, '+
						  '"synchronization method" + 1 as "SynchronizationMethod", '+
						  'alt_snapshot_folder as AltShapshotFolder, '+
						  'snapshot_in_defaultfolder as SnapshotInDefaultFolder '+
						  'FROM #TranPublTemp_GetPublisherInfoQuery '+
						  'UNION ALL '+
						  'SELECT ' + QUOTENAME(DatabaseName, '''') + ' as DatabaseName, ' + 
						  'name as PublicationName, '+
						  '"description" as "Description", '+
						  '3 as "Type", '+
						  '"retention" as "Retention", '+
						  'retention_period_unit + 1 as RetentionInterval, '+
						  'sync_mode + 1 as "SynchronizationMethod", '+
						  'alt_snapshot_folder as AltShapshotFolder, '+
						  'snapshot_in_defaultfolder as SnapshotInDefaultFolder '+
						  'FROM #MergePublTemp_GetPublisherInfoQuery; '+
						  'END TRY ' +
						  'BEGIN CATCH ' +
						  'END CATCH ' +
						  'TRUNCATE TABLE #TranPublTemp_GetPublisherInfoQuery; ' +
						  'TRUNCATE TABLE #MergePublTemp_GetPublisherInfoQuery; '
from @Databases

set @query = @query + 'select @@SERVERNAME Publisher, PublicationName, DatabaseName PublisherDb, AltSnapshotFolder, SnapshotInDefaultFolder from @temp; ' + 
					  'DROP TABLE #TranPublTemp_GetPublisherInfoQuery; ' +
				      'DROP TABLE #MergePublTemp_GetPublisherInfoQuery; '

exec (@query)



--PublicationSubscriptionSyncStatusQuery
-- Type of publication: 0 = Transactional, 1 = Snapshot, 2 = Merge
DECLARE @query NVARCHAR(MAX);

SET @query = N'
DECLARE @in_publisher NVARCHAR(4000) = ' + QUOTENAME(@publisher, N'''') + N';';

SELECT @query = @query + N'

USE ' + QUOTENAME([name]) + N';

EXEC sys.sp_replmonitorhelpsubscription @publisher = @in_publisher, @publication_type = 2;
EXEC sys.sp_replmonitorhelpsubscription @publisher = @in_publisher, @publication_type = 1;
EXEC sys.sp_replmonitorhelpsubscription @publisher = @in_publisher, @publication_type = 0;'
FROM [master].sys.databases
WHERE is_distributor = 1;

EXEC (@query);



--DistributorAgentsLoadQuery
DECLARE @sDelimiter VARCHAR(1) 
SET @sDelimiter = ','
DECLARE @sItem VARCHAR(max)
DECLARE @List TABLE (NAME VARCHAR(max), IS_POSITIVE bit)

WHILE CHARINDEX(@sDelimiter,@sInputPositiveList,0) <> 0
 BEGIN
	
	 SET @sItem = RTRIM(LTRIM(SUBSTRING(@sInputPositiveList,1,CHARINDEX(@sDelimiter,@sInputPositiveList,0)-1)));
	 SET @sInputPositiveList = RTRIM(LTRIM(SUBSTRING(@sInputPositiveList,CHARINDEX(@sDelimiter,@sInputPositiveList,0)+LEN(@sDelimiter),LEN(@sInputPositiveList))))

	IF LEN(@sItem) > 0
		INSERT INTO @List SELECT @sItem, 1
 END
IF LEN(@sInputPositiveList) > 0
	INSERT INTO @List SELECT @sInputPositiveList, 1 


WHILE CHARINDEX(@sDelimiter,@sInputNegativeList,0) <> 0
 BEGIN
	
	 SET @sItem = RTRIM(LTRIM(SUBSTRING(@sInputNegativeList,1,CHARINDEX(@sDelimiter,@sInputNegativeList,0)-1)));
	 SET @sInputNegativeList = RTRIM(LTRIM(SUBSTRING(@sInputNegativeList,CHARINDEX(@sDelimiter,@sInputNegativeList,0)+LEN(@sDelimiter),LEN(@sInputNegativeList))))

	IF LEN(@sItem) > 0
		INSERT INTO @List SELECT @sItem, 0
 END
IF LEN(@sInputNegativeList) > 0
	INSERT INTO @List SELECT @sInputNegativeList, 0

DECLARE @dateHigherBoundary datetime 
SET @dateHigherBoundary = GETDATE()
DECLARE @dateLowerBoundary datetime 
SET @dateLowerBoundary = dateadd(HOUR, -@LAST_HOURS, @dateHigherBoundary)
DECLARE @dateSelectedIntervalLength INT 
SET @dateSelectedIntervalLength = @LAST_HOURS * 3600


;with jobLastOutcomeDate AS(
	SELECT 
		sji.job_id
		,jhi.run_datetime
		,CASE
			WHEN jhi.run_datetime IS NOT NULL THEN dateadd(SECOND, jhi.run_duration, jhi.run_datetime)
			ELSE NULL
		END run_end_datetime
		,CASE
		WHEN jhi.run_datetime IS NULL OR run_duration IS NULL THEN 6
		WHEN jhi.run_datetime >= @dateLowerBoundary AND jhi.run_datetime <= @dateHigherBoundary AND dateadd(SECOND, jhi.run_duration, jhi.run_datetime) <= @dateHigherBoundary THEN 1
		WHEN jhi.run_datetime < @dateLowerBoundary AND dateadd(SECOND, jhi.run_duration, jhi.run_datetime) <= @dateHigherBoundary AND dateadd(SECOND, jhi.run_duration, jhi.run_datetime) >= @dateLowerBoundary THEN 2
		WHEN jhi.run_datetime < @dateLowerBoundary AND dateadd(SECOND, jhi.run_duration, jhi.run_datetime) < @dateLowerBoundary THEN 3
		WHEN jhi.run_datetime >= @dateLowerBoundary AND jhi.run_datetime <= @dateHigherBoundary AND dateadd(SECOND, jhi.run_duration, jhi.run_datetime) > @dateHigherBoundary THEN 4
		WHEN jhi.run_datetime < @dateLowerBoundary AND dateadd(SECOND, jhi.run_duration, jhi.run_datetime) > @dateHigherBoundary THEN 5
		END [Type]
		,jhi.instance_id
	FROM msdb.dbo.sysjobs sji
	outer apply (
		SELECT TOP 1 
			job_id
			,msdb.dbo.agent_datetime(run_date, run_time) run_datetime
			,(CASE
			--hours, minutes and seconds
				WHEN LEN(run_duration) > 4 THEN CONVERT(VARCHAR(4),LEFT(run_duration,LEN(run_duration)-4)) * 3600
				+ LEFT(RIGHT(run_duration,4),2) * 60 + RIGHT(run_duration,2)
				--minutes and seconds
				WHEN LEN(run_duration) = 4 THEN LEFT(run_duration,2) * 60 + RIGHT(run_duration,2)
				WHEN LEN(run_duration) = 3 THEN LEFT(run_duration,1) * 60 + RIGHT(run_duration,2)
				ELSE --only seconds    
					RIGHT(run_duration,2) 
			END) run_duration
			,instance_id
		FROM msdb.dbo.sysjobhistory 
		WHERE step_id = 0
			  AND job_id = sji.job_id
		ORDER BY run_datetime desc
		) jhi
)
SELECT
	job.name JobName,
	jd.TotalRunDuration
FROM
(
	--Get fully executed jobs
	SELECT 
		stat.job_id
		,SUM(stat.run_duration) TotalRunDuration
	FROM 
	(
		SELECT
			job_id
			,(CASE
			--hours, minutes and seconds
				WHEN LEN(history.run_duration) > 4 THEN CONVERT(VARCHAR(4),LEFT(history.run_duration,LEN(history.run_duration)-4)) * 3600
				+ LEFT(RIGHT(history.run_duration,4),2) * 60 + RIGHT(history.run_duration,2)
				--minutes and seconds
				WHEN LEN(history.run_duration) = 4 THEN LEFT(history.run_duration,2) * 60 + RIGHT(history.run_duration,2)
				WHEN LEN(history.run_duration) = 3 THEN LEFT(history.run_duration,1) * 60 + RIGHT(history.run_duration,2)
				ELSE --only seconds    
					RIGHT(history.run_duration,2) 
			END) run_duration
		FROM msdb.dbo.sysjobhistory history
		WHERE 
			history.step_id = 0 
			AND msdb.dbo.agent_datetime(run_date, run_time) >= @dateLowerBoundary
			AND msdb.dbo.agent_datetime(run_date, run_time) <= @dateHigherBoundary

		UNION ALL

		--Get partly executed jobs near the beginning of the interval:
		--jobs that began before the beginning of the interval and ended in the given interval
		SELECT 
			job_id
			,DATEDIFF(SECOND,@dateLowerBoundary,dateadd(SECOND, run_duration, hist.run_start)) run_duration
		FROM (
			SELECT
				job_id,
				instance_id,
				msdb.dbo.agent_datetime(run_date, run_time) run_start
			,(CASE
			--hours, minutes and seconds
				WHEN LEN(history.run_duration) > 4 THEN CONVERT(VARCHAR(4),LEFT(history.run_duration,LEN(history.run_duration)-4)) * 3600
				+ LEFT(RIGHT(history.run_duration,4),2) * 60 + RIGHT(history.run_duration,2)
				--minutes and seconds
				WHEN LEN(history.run_duration) = 4 THEN LEFT(history.run_duration,2) * 60 + RIGHT(history.run_duration,2)
				WHEN LEN(history.run_duration) = 3 THEN LEFT(history.run_duration,1) * 60 + RIGHT(history.run_duration,2)
				ELSE --only seconds    
					RIGHT(history.run_duration,2) 
			END) run_duration
			FROM msdb.dbo.sysjobhistory history
			WHERE 
				step_id = 0
			) hist
		WHERE 
			hist.run_start < @dateLowerBoundary 
			AND dateadd(SECOND, run_duration, hist.run_start) >= @dateLowerBoundary

		UNION ALL

		--Get jobs that are still executing
		SELECT 
			job_id
			,CASE
				WHEN run_datetime < @dateLowerBoundary THEN @dateSelectedIntervalLength
				ELSE DATEDIFF(SECOND,run_datetime,@dateHigherBoundary)
			END run_duration
		FROM 
		(
			SELECT
				hist.job_id
				,MIN(msdb.dbo.agent_datetime(run_date, run_time)) run_datetime
			FROM msdb.dbo.sysjobhistory hist
			JOIN jobLastOutcomeDate jlo ON jlo.job_id = hist.job_id AND (jlo.Type = 1 OR jlo.Type = 3 OR jlo.Type = 6)
			WHERE
				hist.step_id <> 0
				AND (((jlo.Type = 1 OR jlo.Type = 3) AND msdb.dbo.agent_datetime(run_date, run_time) > jlo.run_end_datetime) 
				OR jlo.Type = 6)
				AND msdb.dbo.agent_datetime(run_date, run_time) <= @dateHigherBoundary
			GROUP BY hist.job_id
		) lr

	) stat
	GROUP BY stat.job_id
) jd
JOIN msdb.dbo.sysjobs job ON job.job_id = jd.job_id
JOIN msdb.dbo.syscategories cat on cat.category_id = job.category_id
OUTER APPLY(
	SELECT TOP 1 
	1 AS Continuous
	FROM msdb.dbo.sysjobschedules sjs
	join msdb.dbo.sysschedules ss on ss.schedule_id = sjs.schedule_id
	where sjs.job_id = jd.job_id AND ss.freq_type = 64
) ft
WHERE 
	cat.name      IN(SELECT CASE WHEN NAME LIKE 'REPL-%' THEN NAME ELSE 'REPL-' + NAME END FROM @List where IS_POSITIVE = 1) and 
	cat.name  not IN(SELECT CASE WHEN NAME LIKE 'REPL-%' THEN NAME ELSE 'REPL-' + NAME END FROM @List where IS_POSITIVE = 0)
	and ft.Continuous IS NULL



--PublisherPublicationsQuery
SELECT count(*) as PublisherPublicationsCount FROM 
(SELECT name FROM sys.databases WHERE is_published = 1 
UNION ALL 
SELECT name FROM sys.databases WHERE is_merge_published = 1) a



--PublisherSubscriptionsMonitorQuery
DECLARE @query NVARCHAR(max);

SET @query = N'
USE ' + QUOTENAME(@distributorDb) + N';

DECLARE @replication_servers TABLE (
	server_id INT NOT NULL
	,[name] SYSNAME NOT NULL
	,[data_source] NVARCHAR(4000)
	);
DECLARE @in_publisher NVARCHAR(4000) = N' + QUOTENAME(@publisher, '''') + ';

IF OBJECT_ID(N''dbo.MSreplservers'') IS NOT NULL
	INSERT INTO @replication_servers
	SELECT srvid
		,srvname
		,[data_source]
	FROM dbo.MSreplservers AS r
	INNER JOIN [master].sys.servers AS s ON s.[name] = r.srvname COLLATE SQL_Latin1_General_CP1_CI_AS;
ELSE
	INSERT INTO @replication_servers
	SELECT server_id
		,[name]
		,[data_source]
	FROM [master].sys.servers;

SELECT DISTINCT p.[data_source] AS PublisherName
	,s.[data_source] AS SubscriberName
	,pp.publication AS PublicationName
	,ss.publisher_db AS PublisherDb
	,ss.subscriber_db AS SubscriberDb
	,(
		CASE ss.[status]
			WHEN 0
				THEN ''Inactive''
			WHEN 1
				THEN ''Subscribed''
			WHEN 2
				THEN ''Active''
			ELSE ''Unknown''
			END
		) AS [Status]
FROM @replication_servers p
INNER JOIN (
	SELECT publication_id
		,publisher_db
		,subscriber_db
		,MIN([status]) [status]
		,publisher_id
		,subscriber_id
	FROM dbo.MSsubscriptions
	WHERE [status] <> 2 AND subscriber_id > - 1
	GROUP BY publisher_id
		,publisher_db
		,publication_id
		,subscriber_id
		,subscriber_db
	) ss ON ss.publisher_id = p.server_id
INNER JOIN @replication_servers s ON ss.subscriber_id = s.server_id
INNER JOIN dbo.MSpublications pp ON pp.publication_id = ss.publication_id
WHERE p.name = @in_publisher COLLATE SQL_Latin1_General_CP1_CI_AS;'

EXEC (@query);



Leave a Reply

Your email address will not be published. Required fields are marked *