-- DBAOps Enterprise™ - SQL Agent Jobs
-- Generated: 2026-02-05 08:22:25
-- Jobs: 176
--
-- NOTIFICATION RECIPIENTS: Configure in DBAOps.config.json (NotificationRecipients) or
-- create config.NotificationRecipients table in DBAOpsRepository. Default: dbaops@yourdomain.com
--

-- === DBAOps - Agent Job Audit Collection ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Agent Job Audit Collection')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Agent Job Audit Collection', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Agent Job Audit Collection', @enabled = 1, @description = 'Collects SQL Agent job audit errors from A2_Copy servers.', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Agent Job Audit Collection', @step_name = 'Run Agent Job Audit', @step_id = 1, @subsystem = 'PowerShell', @command = 'powershell.exe -File "{{InstallPath}}\Scripts\Collect-AgentJobAudit_2.ps1"', @on_success_action = 1, @on_fail_action = 4;
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Agent Job Audit Collection', @step_name = 'Send Failure Alert', @step_id = 2, @subsystem = 'TSQL', @command = '
EXEC msdb.dbo.sp_send_dbmail
    @profile_name = ''DBAOpsProfile'',
    @recipients   = ''dbaops@yourdomain.com'',
    @subject      = ''*** SQL ALERT: Job Failure â€“ $(ESCAPE_NONE(JOBNAME)) ***'',
    @body         = ''SQL Agent detected a failure in job "$(ESCAPE_NONE(JOBNAME))" on server "$(ESCAPE_NONE(SRVR))".'',
    @body_format  = ''TEXT'';
', @on_success_action = 1, @on_fail_action = 1;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Agent Job Audit Collection', @name = 'Daily 3AM â€“ Agent Job Audit Collection', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 1, @freq_subday_interval = 0, @active_start_time = 30000;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Agent Job Audit Collection', @server_name = '(local)';
GO

-- === DBAOps â€“ Agent Job Compliance ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps â€“ Agent Job Compliance')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps â€“ Agent Job Compliance', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps â€“ Agent Job Compliance', @enabled = 1, @description = 'Checks failed jobs, disabled jobs, missing schedules, orphaned alerts', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Agent Job Compliance', @step_name = 'Run Compliance Scan', @step_id = 1, @subsystem = 'TSQL', @command = 'EXEC ctl.usp_Collect_JobCompliance;', @on_success_action = 4, @on_fail_action = 4;
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Agent Job Compliance', @step_name = 'Send Compliance Report', @step_id = 2, @subsystem = 'TSQL', @command = 'EXEC DBAOpsRepository.ctl.usp_JobComplianceReport @SendEmail = 1;', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps â€“ Agent Job Compliance', @name = 'Every 30 Minutes', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 4, @freq_subday_interval = 30, @active_start_time = 0;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps â€“ Agent Job Compliance', @server_name = '(local)';
GO

-- === DBAOps - Aggregate Performance Daily ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Aggregate Performance Daily')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Aggregate Performance Daily', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Aggregate Performance Daily', @enabled = 1, @description = 'Aggregate performance metrics for previous day', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Aggregate Performance Daily', @step_name = 'Execute', @step_id = 1, @subsystem = 'TSQL', @command = 'EXEC DBAOpsRepository.etl.usp_AggregatePerformanceDaily;', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Aggregate Performance Daily', @name = 'DBAOps - Aggregate Performance Daily Schedule', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 1, @freq_subday_interval = 0, @active_start_time = 10000;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Aggregate Performance Daily', @server_name = '(local)';
GO

-- === DBAOps - AI Scheduled Diagnostics ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - AI Scheduled Diagnostics')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - AI Scheduled Diagnostics', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - AI Scheduled Diagnostics', @enabled = 0, @description = 'DBAOps AI-powered diagnostics and anomaly detection. Enable after configuring Azure OpenAI.', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - AI Scheduled Diagnostics', @step_name = 'Run Anomaly Detection', @step_id = 1, @subsystem = 'TSQL', @command = '
USE DBAOpsRepository;
EXEC AI.usp_DetectAnomalies @LookbackHours = 24, @DeviationThreshold = 2.0;
', @on_success_action = 3, @on_fail_action = 3;
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - AI Scheduled Diagnostics', @step_name = 'Generate AI Summary', @step_id = 2, @subsystem = 'TSQL', @command = '
USE DBAOpsRepository;

DECLARE @Summary NVARCHAR(MAX) = '''';

-- Anomalies detected today
SELECT @Summary = @Summary + ''Anomalies Detected: '' + CAST(COUNT(*) AS VARCHAR) + CHAR(13)
FROM AI.AnomalyDetections
WHERE CAST(DetectedDate AS DATE) = CAST(GETDATE() AS DATE);

-- New recommendations (FIXED: use GeneratedAt instead of CreatedDate)
SELECT @Summary = @Summary + ''New Recommendations: '' + CAST(COUNT(*) AS VARCHAR) + CHAR(13)
FROM AI.Recommendations
WHERE Status = ''New'' AND CAST(GeneratedAt AS DATE) = CAST(GETDATE() AS DATE);

-- Searches performed
SELECT @Summary = @Summary + ''Searches Today: '' + CAST(COUNT(*) AS VARCHAR) + CHAR(13)
FROM AI.SearchHistory
WHERE CAST(SearchTime AS DATE) = CAST(GETDATE() AS DATE);

-- Servers needing attention
SELECT @Summary = @Summary + ''Servers Needing Attention: '' + CAST(COUNT(*) AS VARCHAR) + CHAR(13)
FROM dashboard.vw_ServersNeedingAttention;

PRINT ''DBAOps AI Daily Summary'';
PRINT ''========================'';
PRINT @Summary;
', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - AI Scheduled Diagnostics', @name = 'DBAOps AI Daily Schedule', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 1, @freq_subday_interval = 0, @active_start_time = 60000;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - AI Scheduled Diagnostics', @server_name = '(local)';
GO

-- === DBAOps â€“ Architecture Assessment ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps â€“ Architecture Assessment')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps â€“ Architecture Assessment', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps â€“ Architecture Assessment', @enabled = 1, @description = 'DBAOps: Runs automated architecture assessment and sends notification reports. Author: RHOYLLE INNOVATION EMPIRE LLC', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Architecture Assessment', @step_name = 'Run Architecture Assessment', @step_id = 1, @subsystem = 'TSQL', @command = 'EXEC Assessment.usp_RunArchitectureAssessment @SendNotification = 1, @ForceNotification = 1;', @on_success_action = 3, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Architecture Assessment', @step_name = 'Cleanup Old History', @step_id = 2, @subsystem = 'TSQL', @command = 'EXEC Assessment.usp_CleanupHistory;', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps â€“ Architecture Assessment', @name = 'Daily Assessment - 7AM', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 1, @freq_subday_interval = 0, @active_start_time = 70000;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps â€“ Architecture Assessment', @server_name = '(local)';
GO

-- === DBAOps - Architecture Compliance Monitor ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Architecture Compliance Monitor')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Architecture Compliance Monitor', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Architecture Compliance Monitor', @enabled = 1, @description = 'Run architecture maturity assessment', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Architecture Compliance Monitor', @step_name = 'Execute', @step_id = 1, @subsystem = 'TSQL', @command = 'EXEC Assessment.usp_RunArchitectureAssessment @SendNotification = 1;', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Architecture Compliance Monitor', @name = 'DBAOps - Architecture Compliance Monitor Schedule', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 1, @freq_subday_interval = 0, @active_start_time = 70000;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Architecture Compliance Monitor', @server_name = '(local)';
GO

-- === DBAOps - Audit Login Activity ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Audit Login Activity')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Audit Login Activity', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Audit Login Activity', @enabled = 1, @description = 'Capture login success and failure events', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Audit Login Activity', @step_name = 'Execute', @step_id = 1, @subsystem = 'TSQL', @command = 'EXEC DBAOpsRepository.audit.usp_AuditLoginActivity;', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Audit Login Activity', @name = 'DBAOps - Audit Login Activity Schedule', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 4, @freq_subday_interval = 15, @active_start_time = 0;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Audit Login Activity', @server_name = '(local)';
GO

-- === DBAOps â€“ Backup Compliance Collector ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps â€“ Backup Compliance Collector')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps â€“ Backup Compliance Collector', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps â€“ Backup Compliance Collector', @enabled = 1, @description = 'Collects backup compliance data', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Backup Compliance Collector', @step_name = 'Collect Compliance', @step_id = 1, @subsystem = 'TSQL', @command = 'EXEC ctl.usp_Fact_AutoHeal_All;', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps â€“ Backup Compliance Collector', @name = 'DBAOps â€“ Every 15 Minutes', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 4, @freq_subday_interval = 15, @active_start_time = 0;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps â€“ Backup Compliance Collector', @server_name = '(local)';
GO

-- === DBAOps â€“ Backup Compliance Daily Email ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps â€“ Backup Compliance Daily Email')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps â€“ Backup Compliance Daily Email', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps â€“ Backup Compliance Daily Email', @enabled = 1, @description = 'No description available.', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Backup Compliance Daily Email', @step_name = 'Send Backup SLA Email', @step_id = 1, @subsystem = 'TSQL', @command = 'EXEC DBAOpsRepository.meta.usp_BackupCompliance_DailyEmail;', @on_success_action = 1, @on_fail_action = 4;
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Backup Compliance Daily Email', @step_name = 'Send Failure Alert', @step_id = 2, @subsystem = 'TSQL', @command = '
EXEC msdb.dbo.sp_send_dbmail
    @profile_name = ''DBAOpsProfile'',
    @recipients   = ''dbaops@yourdomain.com'',
    @subject      = ''*** SQL ALERT: Job Failure â€“ $(ESCAPE_NONE(JOBNAME)) ***'',
    @body         = ''SQL Agent detected a failure in job "$(ESCAPE_NONE(JOBNAME))" on server "$(ESCAPE_NONE(SRVR))".'',
    @body_format  = ''TEXT'';
', @on_success_action = 1, @on_fail_action = 1;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps â€“ Backup Compliance Daily Email', @name = 'Daily 7:05AM', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 1, @freq_subday_interval = 0, @active_start_time = 70500;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps â€“ Backup Compliance Daily Email', @server_name = '(local)';
GO

-- === DBAOps â€“ Backup Compliance Report ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps â€“ Backup Compliance Report')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps â€“ Backup Compliance Report', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps â€“ Backup Compliance Report', @enabled = 1, @description = 'Sends backup compliance summary report every 30 minutes', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Backup Compliance Report', @step_name = 'Send Compliance Report', @step_id = 1, @subsystem = 'TSQL', @command = 'EXEC DBAOpsRepository.alert.usp_BackupComplianceDailyReport;', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps â€“ Backup Compliance Report', @name = 'Every 30 Minutes', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 4, @freq_subday_interval = 30, @active_start_time = 0;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps â€“ Backup Compliance Report', @server_name = '(local)';
GO

-- === DBAOps â€“ Blocking Monitor ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps â€“ Blocking Monitor')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps â€“ Blocking Monitor', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps â€“ Blocking Monitor', @enabled = 1, @description = 'Detects blocking processes across all servers; stores and alerts.', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Blocking Monitor', @step_name = 'Collect Blocking', @step_id = 1, @subsystem = 'TSQL', @command = 'EXEC dbo.usp_CollectBlockingEvents @Debug = 0;', @on_success_action = 1, @on_fail_action = 4;
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Blocking Monitor', @step_name = 'Send Failure Alert', @step_id = 2, @subsystem = 'TSQL', @command = '
EXEC msdb.dbo.sp_send_dbmail
    @profile_name = ''DBAOpsProfile'',
    @recipients   = ''dbaops@yourdomain.com'',
    @subject      = ''*** SQL ALERT: Job Failure â€“ $(ESCAPE_NONE(JOBNAME)) ***'',
    @body         = ''SQL Agent detected a failure in job "$(ESCAPE_NONE(JOBNAME))" on server "$(ESCAPE_NONE(SRVR))".'',
    @body_format  = ''TEXT'';
', @on_success_action = 1, @on_fail_action = 1;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps â€“ Blocking Monitor', @name = 'Every 5 Minutes', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 4, @freq_subday_interval = 5, @active_start_time = 0;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps â€“ Blocking Monitor', @server_name = '(local)';
GO

-- === DBAOps - Calculate Growth Trends ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Calculate Growth Trends')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Calculate Growth Trends', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Calculate Growth Trends', @enabled = 1, @description = 'Calculate database and storage growth trends', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Calculate Growth Trends', @step_name = 'Execute', @step_id = 1, @subsystem = 'TSQL', @command = 'EXEC capacity.usp_CalculateGrowthTrends;', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Calculate Growth Trends', @name = 'DBAOps - Calculate Growth Trends Schedule', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 1, @freq_subday_interval = 0, @active_start_time = 20000;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Calculate Growth Trends', @server_name = '(local)';
GO

-- === DBAOps - Capacity Forecast Calculator ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Capacity Forecast Calculator')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Capacity Forecast Calculator', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Capacity Forecast Calculator', @enabled = 1, @description = 'Calculates growth forecasts and capacity predictions. Part of DBAOps monitoring platform.', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Capacity Forecast Calculator', @step_name = 'Calculate Growth Forecasts', @step_id = 1, @subsystem = 'TSQL', @command = '
-- Clear old forecasts
DELETE FROM DBAOpsRepository.capacity.GrowthForecast WHERE CalculatedAt < DATEADD(DAY, -7, GETDATE());
-- Calculate new forecasts
EXEC DBAOpsRepository.capacity.usp_CalculateGrowthForecast @DaysHistory = 30;
PRINT ''Capacity forecasts calculated successfully'';', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Capacity Forecast Calculator', @name = 'Daily at 6 AM', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 1, @freq_subday_interval = 0, @active_start_time = 60000;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Capacity Forecast Calculator', @server_name = '(local)';
GO

-- === DBAOps - Capture Schema Changes ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Capture Schema Changes')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Capture Schema Changes', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Capture Schema Changes', @enabled = 1, @description = 'Capture DDL events from all servers', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Capture Schema Changes', @step_name = 'Execute', @step_id = 1, @subsystem = 'TSQL', @command = 'EXEC change.usp_CaptureSchemaChanges;', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Capture Schema Changes', @name = 'DBAOps - Capture Schema Changes Schedule', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 4, @freq_subday_interval = 15, @active_start_time = 0;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Capture Schema Changes', @server_name = '(local)';
GO

-- === DBAOps - Change Timeline Collector ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Change Timeline Collector')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Change Timeline Collector', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Change Timeline Collector', @enabled = 1, @description = 'Collects configuration changes, patches, and system events into unified timeline.', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Change Timeline Collector', @step_name = 'Collect Config Changes', @step_id = 1, @subsystem = 'TSQL', @command = '
-- Detect sp_configure changes by comparing to baseline
-- This is a placeholder - customize based on your baseline tracking
DECLARE @ServerName NVARCHAR(128) = @@SERVERNAME;

-- Check for recent SQL errorlog config messages
INSERT INTO change.UnifiedTimeline (ChangeTypeID, ServerName, CMSGroupName, ChangeDateTime, ChangeDescription, SourceSystem)
SELECT 
    (SELECT ChangeTypeID FROM change.ChangeTypes WHERE ChangeTypeName = ''sp_configure Change''),
    @ServerName,
    (SELECT TOP 1 CMSGroupName FROM config.ServerInventory WHERE ServerName = @ServerName),
    GETDATE(),
    ''Configuration check completed'',
    ''SQL Agent''
WHERE NOT EXISTS (
    SELECT 1 FROM change.UnifiedTimeline 
    WHERE ServerName = @ServerName 
    AND ChangeDateTime > DATEADD(MINUTE, -15, GETDATE())
    AND SourceSystem = ''SQL Agent''
);

PRINT ''Config change check completed'';', @on_success_action = 3, @on_fail_action = 3;
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Change Timeline Collector', @step_name = 'Collect Patch Events', @step_id = 2, @subsystem = 'TSQL', @command = '
-- Sync recent patches from Patching schema to timeline
INSERT INTO change.UnifiedTimeline (ChangeTypeID, ServerName, CMSGroupName, CMSCriticality, ChangeDateTime, ChangeDescription, SourceSystem, SourceReference, IsPlanned)
SELECT DISTINCT
    (SELECT ChangeTypeID FROM change.ChangeTypes WHERE ChangeTypeName = ''SQL Patch/CU''),
    p.ServerName,
    si.CMSGroupName,
    si.CMSCriticality,
    p.PatchDate,
    CONCAT(''SQL Server patch applied: '', p.KBNumber, ISNULL('' - '' + p.PatchType, '''')),
    ''Patching'',
    p.KBNumber,
    1
FROM Patching.PatchHistory p
JOIN config.ServerInventory si ON p.ServerName = si.ServerName
WHERE p.PatchDate > DATEADD(DAY, -1, GETDATE())
  AND NOT EXISTS (
    SELECT 1 FROM change.UnifiedTimeline t 
    WHERE t.ServerName = p.ServerName 
    AND t.SourceReference = p.KBNumber
    AND t.ChangeDateTime = p.PatchDate
  );

PRINT CONCAT(''Patch events synced: '', @@ROWCOUNT);
', @on_success_action = 3, @on_fail_action = 3;
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Change Timeline Collector', @step_name = 'Collect Service Restarts', @step_id = 3, @subsystem = 'TSQL', @command = '
DECLARE @ServerName NVARCHAR(128) = @@SERVERNAME;
DECLARE @LastRestart DATETIME;

SELECT @LastRestart = sqlserver_start_time FROM sys.dm_os_sys_info;

-- Record if restart happened in last 15 minutes
IF @LastRestart > DATEADD(MINUTE, -15, GETDATE())
BEGIN
    IF NOT EXISTS (SELECT 1 FROM change.UnifiedTimeline WHERE ServerName = @ServerName AND ChangeDateTime = @LastRestart)
    BEGIN
        EXEC change.usp_RecordChange
            @ChangeTypeName = ''SQL Service Restart'',
            @ServerName = @ServerName,
            @ChangeDescription = ''SQL Server service restarted'',
            @SourceSystem = ''SQL Agent'',
            @ChangeDateTime = @LastRestart;
        PRINT ''Service restart recorded'';
    END
END', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Change Timeline Collector', @name = 'Every15Min_ChangeTimeline', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 4, @freq_subday_interval = 15, @active_start_time = 0;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Change Timeline Collector', @server_name = '(local)';
GO

-- === DBAOps - Check Maintenance Health ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Check Maintenance Health')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Check Maintenance Health', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Check Maintenance Health', @enabled = 1, @description = 'Checks for maintenance failures and sends alert email if issues found.', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Check Maintenance Health', @step_name = 'Check Health', @step_id = 1, @subsystem = 'TSQL', @command = 'EXEC DBAOpsRepository.dbo.usp_CheckMaintenanceHealth @HoursBack = 24, @SendEmail = 1;', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Check Maintenance Health', @name = 'DBAOps Daily 7AM Health Check', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 1, @freq_subday_interval = 0, @active_start_time = 70000;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Check Maintenance Health', @server_name = '(local)';
GO

-- === DBAOps - Cleanup Maintenance Logs ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Cleanup Maintenance Logs')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Cleanup Maintenance Logs', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Cleanup Maintenance Logs', @enabled = 1, @description = 'Removes maintenance log entries older than 90 days.', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Cleanup Maintenance Logs', @step_name = 'Cleanup', @step_id = 1, @subsystem = 'TSQL', @command = 'EXEC DBAOpsRepository.dbo.usp_CleanupMaintenanceLogs @RetentionDays = 90;', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Cleanup Maintenance Logs', @name = 'Sunday 4AM', @freq_type = 8, @freq_interval = 1, @freq_subday_type = 1, @freq_subday_interval = 0, @active_start_time = 40000;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Cleanup Maintenance Logs', @server_name = '(local)';
GO

-- === DBAOps - Collect Audit Events ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Collect Audit Events')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Collect Audit Events', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Collect Audit Events', @enabled = 1, @description = 'DBAOps: Collects login failures, permission changes, and object changes', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Collect Audit Events', @step_name = 'Collect Login Failures', @step_id = 1, @subsystem = 'TSQL', @command = 'EXEC audit.usp_Collect_LoginFailures;', @on_success_action = 3, @on_fail_action = 3;
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Collect Audit Events', @step_name = 'Collect Permission Changes', @step_id = 2, @subsystem = 'TSQL', @command = 'EXEC audit.usp_Collect_PermissionChanges;', @on_success_action = 3, @on_fail_action = 3;
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Collect Audit Events', @step_name = 'Collect Object Changes', @step_id = 3, @subsystem = 'TSQL', @command = 'EXEC audit.usp_Collect_ObjectChanges;', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Collect Audit Events', @name = 'Every 15 Minutes', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 4, @freq_subday_interval = 15, @active_start_time = 0;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Collect Audit Events', @server_name = '(local)';
GO

-- === DBAOps â€“ Collect Backup Compliance ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps â€“ Collect Backup Compliance')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps â€“ Collect Backup Compliance', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps â€“ Collect Backup Compliance', @enabled = 1, @description = 'Loads Veeam backup compliance data into staging, ctl and fact tables.', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Collect Backup Compliance', @step_name = 'Step 3 â€“ Load Fact.Layer', @step_id = 1, @subsystem = 'TSQL', @command = '
        INSERT INTO fact.BackupCompliance
        (
            LoadDate, BackupSource, ServerName, VmName,
            BackupType, LastBackupTime, NextExpectedBackupTime,
            Status, BackupMode
        )
        SELECT
            GETDATE(),
            BackupSource, ServerName, VmName,
            BackupType, LastBackupTime, NextExpectedBackupTime,
            Status, BackupMode
        FROM ctl.BackupCompliance;
    ', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Collect Backup Compliance', @step_name = 'Run Backup Compliance ETL', @step_id = 2, @subsystem = 'TSQL', @command = '
-----------------------------------------------------------
-- STEP 1: Load latest Veeam backups into staging
-----------------------------------------------------------
TRUNCATE TABLE staging.VeeamBackups;

INSERT INTO staging.VeeamBackups
SELECT * FROM etl.VeeamBackups;  -- raw source table

-----------------------------------------------------------
-- STEP 2: Insert into ctl.BackupCompliance
-----------------------------------------------------------
INSERT INTO ctl.BackupCompliance
(
    BackupSource, ServerName, VmName, DatabaseName, BackupType,
    LastBackupTime, NextExpectedBackupTime, CollectionTime, JobName,
    Status, BackupMode
)
SELECT
    ''Veeam'',
    v.JobName,
    v.JobName,
    NULL,
    ISNULL(v.BackupType, ''Unknown''),
    v.EndTime,
    DATEADD(HOUR, 24, v.EndTime),
    GETDATE(),
    v.JobName,
    CASE WHEN DATEDIFF(HOUR, v.EndTime, GETDATE()) <= 24 THEN ''Success'' ELSE ''Stale'' END,
    v.BackupType
FROM staging.VeeamBackups v
WHERE v.EndTime IS NOT NULL;

-----------------------------------------------------------
-- STEP 3: Update metrics & fact tables (placeholders)
-- Add your scoring + anomaly detection logic here
-----------------------------------------------------------

-- Example: update ComplianceScore
UPDATE c
SET c.ComplianceScore = 75
FROM ctl.BackupCompliance c
WHERE c.ComplianceScore IS NULL;

-----------------------------------------------------------
-- STEP 4: Log the ETL run
-----------------------------------------------------------
INSERT INTO meta.BackupComplianceLog (LoadDate, RecordsProcessed)
SELECT GETDATE(), COUNT(*) FROM ctl.BackupCompliance;
', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps â€“ Collect Backup Compliance', @name = 'DBAOps_Every_15_Minutes', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 4, @freq_subday_interval = 15, @active_start_time = 0;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps â€“ Collect Backup Compliance', @server_name = '(local)';
GO

-- === DBAOps - Collect Backup Telemetry ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Collect Backup Telemetry')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Collect Backup Telemetry', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Collect Backup Telemetry', @enabled = 1, @description = 'Collect backup history from all servers', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Collect Backup Telemetry', @step_name = 'Execute', @step_id = 1, @subsystem = 'TSQL', @command = 'EXEC DBAOpsRepository.etl.usp_CollectBackupTelemetry;', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Collect Backup Telemetry', @name = 'DBAOps - Collect Backup Telemetry Schedule', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 4, @freq_subday_interval = 15, @active_start_time = 0;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Collect Backup Telemetry', @server_name = '(local)';
GO

-- === DBAOps â€“ Collect Database File Inventory ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps â€“ Collect Database File Inventory')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps â€“ Collect Database File Inventory', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps â€“ Collect Database File Inventory', @enabled = 1, @description = 'Collects file-level metadata from all SQL Servers in A2 list', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Collect Database File Inventory', @step_name = 'Run PS Script', @step_id = 1, @subsystem = 'PowerShell', @command = 'powershell.exe -ExecutionPolicy Bypass -File "{{InstallPath}}\Scripts\Collect-DatabaseFileInventory.ps1"', @on_success_action = 1, @on_fail_action = 4;
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Collect Database File Inventory', @step_name = 'Send Failure Alert', @step_id = 2, @subsystem = 'TSQL', @command = '
EXEC msdb.dbo.sp_send_dbmail
    @profile_name = ''DBAOpsProfile'',
    @recipients   = ''dbaops@yourdomain.com'',
    @subject      = ''*** SQL ALERT: Job Failure â€“ $(ESCAPE_NONE(JOBNAME)) ***'',
    @body         = ''SQL Agent detected a failure in job "$(ESCAPE_NONE(JOBNAME))" on server "$(ESCAPE_NONE(SRVR))".'',
    @body_format  = ''TEXT'';
', @on_success_action = 1, @on_fail_action = 1;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps â€“ Collect Database File Inventory', @name = 'Daily 1:40AM Inventory', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 1, @freq_subday_interval = 0, @active_start_time = 14000;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps â€“ Collect Database File Inventory', @server_name = '(local)';
GO

-- === DBAOps - Collect Database Inventory ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Collect Database Inventory')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Collect Database Inventory', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Collect Database Inventory', @enabled = 1, @description = 'Refresh database inventory from all servers', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Collect Database Inventory', @step_name = 'Execute', @step_id = 1, @subsystem = 'TSQL', @command = 'EXEC DBAOps.usp_CollectDatabaseInventory;', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Collect Database Inventory', @name = 'DBAOps - Collect Database Inventory Schedule', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 1, @freq_subday_interval = 0, @active_start_time = 61500;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Collect Database Inventory', @server_name = '(local)';
GO

-- === DBAOps â€“ Collect DDL Audit ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps â€“ Collect DDL Audit')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps â€“ Collect DDL Audit', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps â€“ Collect DDL Audit', @enabled = 1, @description = 'Harvest DDL Extended Events from all servers listed in dbo.A2 and insert into audit.ObjectChanges.', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Collect DDL Audit', @step_name = 'Collect XE Events', @step_id = 1, @subsystem = 'TSQL', @command = 'EXEC dbo.usp_Collect_DDL_AuditEvents_WithReport;', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps â€“ Collect DDL Audit', @name = 'Every 30 Minutes', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 4, @freq_subday_interval = 30, @active_start_time = 0;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps â€“ Collect DDL Audit', @server_name = '(local)';
GO

-- === DBAOps - Collect Disk Space ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Collect Disk Space')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Collect Disk Space', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Collect Disk Space', @enabled = 1, @description = 'Collect disk space metrics from all servers', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Collect Disk Space', @step_name = 'Execute', @step_id = 1, @subsystem = 'TSQL', @command = 'EXEC DBAOpsRepository.inventory.usp_CollectDiskSpace;', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Collect Disk Space', @name = 'DBAOps - Collect Disk Space Schedule', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 4, @freq_subday_interval = 30, @active_start_time = 0;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Collect Disk Space', @server_name = '(local)';
GO

-- === DBAOps â€“ Collect Disk Space (dbatools) ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps â€“ Collect Disk Space (dbatools)')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps â€“ Collect Disk Space (dbatools)', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps â€“ Collect Disk Space (dbatools)', @enabled = 1, @description = 'Collects disk space from all SQL Servers using dbatools PowerShell. Runs every 15 minutes. Author: RHOYLLE INNOVATION EMPIRE LLC', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Collect Disk Space (dbatools)', @step_name = 'Collect Disk Space', @step_id = 1, @subsystem = 'PowerShell', @command = 'powershell.exe -ExecutionPolicy Bypass -File "{{InstallPath}}\Scripts\Collect-DiskSpace.ps1"', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps â€“ Collect Disk Space (dbatools)', @name = 'DBAOps_DiskSpace_Every_15_Min', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 4, @freq_subday_interval = 15, @active_start_time = 0;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps â€“ Collect Disk Space (dbatools)', @server_name = '(local)';
GO

-- === DBAOps â€“ Collect Disk Space Metrics ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps â€“ Collect Disk Space Metrics')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps â€“ Collect Disk Space Metrics', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps â€“ Collect Disk Space Metrics', @enabled = 1, @description = 'Collects disk space from all servers in A2 using dbatools PowerShell.', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Collect Disk Space Metrics', @step_name = 'Run DiskSpace Collector', @step_id = 1, @subsystem = 'PowerShell', @command = 'powershell.exe -NoProfile -ExecutionPolicy Bypass -File "{{InstallPath}}\Scripts\Collect-DiskSpace.ps1"', @on_success_action = 1, @on_fail_action = 4;
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Collect Disk Space Metrics', @step_name = 'Send Failure Alert', @step_id = 2, @subsystem = 'TSQL', @command = '
EXEC msdb.dbo.sp_send_dbmail
    @profile_name = ''DBAOpsProfile'',
    @recipients   = ''dbaops@yourdomain.com'',
    @subject      = ''*** SQL ALERT: Job Failure â€“ $(ESCAPE_NONE(JOBNAME)) ***'',
    @body         = ''SQL Agent detected a failure in job "$(ESCAPE_NONE(JOBNAME))" on server "$(ESCAPE_NONE(SRVR))".'',
    @body_format  = ''TEXT'';
', @on_success_action = 1, @on_fail_action = 1;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps â€“ Collect Disk Space Metrics', @name = 'DBAOps â€“ Every 15 Minutes', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 4, @freq_subday_interval = 15, @active_start_time = 0;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps â€“ Collect Disk Space Metrics', @server_name = '(local)';
GO

-- === DBAOps - Collect ETL Job History ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Collect ETL Job History')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Collect ETL Job History', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Collect ETL Job History', @enabled = 1, @description = 'Collects SSIS job history. V2.1 FINAL with explicit parameters.', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Collect ETL Job History', @step_name = 'Run SSIS Audit Collection Script', @step_id = 1, @subsystem = 'PowerShell', @command = 'Set-Location "{{InstallPath}}\Scripts\ETL\Compliance"; .\Collect-Legacy-SSIS-Audit.ps1 -CentralServer $env:COMPUTERNAME -CentralDatabase "DBAOpsRepository" -CollectionIntervalMinutes 15', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Collect ETL Job History', @name = 'Every 15 Minutes', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 4, @freq_subday_interval = 15, @active_start_time = 0;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Collect ETL Job History', @server_name = '(local)';
GO

-- === DBAOps â€“ Collect Expensive Queries ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps â€“ Collect Expensive Queries')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps â€“ Collect Expensive Queries', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps â€“ Collect Expensive Queries', @enabled = 1, @description = 'Collects top 20 highest CPU-consuming queries from all servers.', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Collect Expensive Queries', @step_name = 'Run Collect-ExpensiveQueries', @step_id = 1, @subsystem = 'PowerShell', @command = '& "{{InstallPath}}\PowerShell\Collect-ExpensiveQueries.ps1"', @on_success_action = 1, @on_fail_action = 4;
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Collect Expensive Queries', @step_name = 'Send Failure Alert', @step_id = 2, @subsystem = 'TSQL', @command = '
EXEC msdb.dbo.sp_send_dbmail
    @profile_name = ''DBAOpsProfile'',
    @recipients   = ''dbaops@yourdomain.com'',
    @subject      = ''*** SQL ALERT: Job Failure â€“ $(ESCAPE_NONE(JOBNAME)) ***'',
    @body         = ''SQL Agent detected a failure in job "$(ESCAPE_NONE(JOBNAME))" on server "$(ESCAPE_NONE(SRVR))".'',
    @body_format  = ''TEXT'';
', @on_success_action = 1, @on_fail_action = 1;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps â€“ Collect Expensive Queries', @name = 'Every 30 Minutes', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 4, @freq_subday_interval = 30, @active_start_time = 0;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps â€“ Collect Expensive Queries', @server_name = '(local)';
GO

-- === DBAOps â€“ Collect Full Server Inventory ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps â€“ Collect Full Server Inventory')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps â€“ Collect Full Server Inventory', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps â€“ Collect Full Server Inventory', @enabled = 1, @description = 'Collects database inventory from all SQL Servers and loads into DBAOpsRepository', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Collect Full Server Inventory', @step_name = 'Run PowerShell Inventory Script', @step_id = 1, @subsystem = 'PowerShell', @command = 'powershell.exe -ExecutionPolicy Bypass -File "{{InstallPath}}\Scripts\Collect-FullServerInventory.ps1"', @on_success_action = 1, @on_fail_action = 4;
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Collect Full Server Inventory', @step_name = 'Collect Inventory via PowerShell', @step_id = 2, @subsystem = 'PowerShell', @command = 'powershell.exe -ExecutionPolicy Bypass -File "{{InstallPath}}\Scripts\Collect-FullServerInventory.ps1"', @on_success_action = 1, @on_fail_action = 4;
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Collect Full Server Inventory', @step_name = 'Run Inventory Collection', @step_id = 3, @subsystem = 'PowerShell', @command = 'powershell.exe -ExecutionPolicy Bypass -File "{{InstallPath}}\Scripts\Collect-FullServerInventory.ps1"', @on_success_action = 1, @on_fail_action = 4;
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Collect Full Server Inventory', @step_name = 'Send Failure Alert', @step_id = 4, @subsystem = 'TSQL', @command = '
EXEC msdb.dbo.sp_send_dbmail
    @profile_name = ''DBAOpsProfile'',
    @recipients   = ''dbaops@yourdomain.com'',
    @subject      = ''*** SQL ALERT: Job Failure â€“ $(ESCAPE_NONE(JOBNAME)) ***'',
    @body         = ''SQL Agent detected a failure in job "$(ESCAPE_NONE(JOBNAME))" on server "$(ESCAPE_NONE(SRVR))".'',
    @body_format  = ''TEXT'';
', @on_success_action = 1, @on_fail_action = 1;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps â€“ Collect Full Server Inventory', @name = 'Daily 1:30AM Inventory', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 1, @freq_subday_interval = 0, @active_start_time = 13000;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps â€“ Collect Full Server Inventory', @server_name = '(local)';
GO

-- === DBAOps - Collect Instance Inventory ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Collect Instance Inventory')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Collect Instance Inventory', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Collect Instance Inventory', @enabled = 1, @description = 'Collects SQL instance metadata from all servers in A2', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Collect Instance Inventory', @step_name = 'Run Instance Inventory Script', @step_id = 1, @subsystem = 'PowerShell', @command = 'powershell.exe -ExecutionPolicy Bypass -File "{{InstallPath}}\Scripts\Collect-InstanceInventory.ps1"', @on_success_action = 1, @on_fail_action = 4;
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Collect Instance Inventory', @step_name = 'Send Failure Alert', @step_id = 2, @subsystem = 'TSQL', @command = '
EXEC msdb.dbo.sp_send_dbmail
    @profile_name = ''DBAOpsProfile'',
    @recipients   = ''dbaops@yourdomain.com'',
    @subject      = ''*** SQL ALERT: Job Failure â€“ $(ESCAPE_NONE(JOBNAME)) ***'',
    @body         = ''SQL Agent detected a failure in job "$(ESCAPE_NONE(JOBNAME))" on server "$(ESCAPE_NONE(SRVR))".'',
    @body_format  = ''TEXT'';
', @on_success_action = 1, @on_fail_action = 1;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Collect Instance Inventory', @name = 'Daily 1:35AM Inventory', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 1, @freq_subday_interval = 0, @active_start_time = 13500;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Collect Instance Inventory', @server_name = '(local)';
GO

-- === DBAOps - Collect Job History ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Collect Job History')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Collect Job History', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Collect Job History', @enabled = 1, @description = 'Collects SQL Agent job history from all monitored servers for central reporting', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Collect Job History', @step_name = 'Collect Job History', @step_id = 1, @subsystem = 'TSQL', @command = 'EXEC DBAOpsRepository.metrics.usp_CollectJobHistory @HoursBack = 24;', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Collect Job History', @name = 'Every 15 minutes', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 4, @freq_subday_interval = 15, @active_start_time = 0;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Collect Job History', @server_name = '(local)';
GO

-- === DBAOps â€“ Collect Job Integrity Audit ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps â€“ Collect Job Integrity Audit')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps â€“ Collect Job Integrity Audit', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps â€“ Collect Job Integrity Audit', @enabled = 1, @description = 'Collects integrity, compliance, scheduling, and health data for SQL Agent jobs.', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Collect Job Integrity Audit', @step_name = 'Run Job Integrity Collector', @step_id = 1, @subsystem = 'TSQL', @command = 'EXEC DBAOpsRepository.dbo.usp_Collect_JobIntegrityAudit;', @on_success_action = 1, @on_fail_action = 4;
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Collect Job Integrity Audit', @step_name = 'Send Failure Alert', @step_id = 2, @subsystem = 'TSQL', @command = '
EXEC msdb.dbo.sp_send_dbmail
    @profile_name = ''DBAOpsProfile'',
    @recipients   = ''dbaops@yourdomain.com'',
    @subject      = ''*** SQL ALERT: Job Failure â€“ $(ESCAPE_NONE(JOBNAME)) ***'',
    @body         = ''SQL Agent detected a failure in job "$(ESCAPE_NONE(JOBNAME))" on server "$(ESCAPE_NONE(SRVR))".'',
    @body_format  = ''TEXT'';
', @on_success_action = 1, @on_fail_action = 1;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps â€“ Collect Job Integrity Audit', @name = 'Every 1 Hour', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 8, @freq_subday_interval = 1, @active_start_time = 0;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps â€“ Collect Job Integrity Audit', @server_name = '(local)';
GO

-- === DBAOps - Collect Linked Server Inventory ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Collect Linked Server Inventory')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Collect Linked Server Inventory', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Collect Linked Server Inventory', @enabled = 1, @description = 'Collects linked server configurations from all SQL Server instances. Migrated from AZSQLADMIN19\SQL2019 job [Linked_Servers].', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Collect Linked Server Inventory', @step_name = 'Truncate table Linked_Servers_Load', @step_id = 1, @subsystem = 'TSQL', @command = 'TRUNCATE TABLE inventory.Linked_Servers_Load;', @on_success_action = 3, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Collect Linked Server Inventory', @step_name = 'PowerShell - Collect Linked Servers', @step_id = 2, @subsystem = 'PowerShell', @command = 'powershell.exe -ExecutionPolicy Bypass -File "{{InstallPath}}\Scripts\Collect-LinkedServers.ps1"', @on_success_action = 3, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Collect Linked Server Inventory', @step_name = 'Merge Linked Servers Data', @step_id = 3, @subsystem = 'TSQL', @command = 'EXEC inventory.usp_Merge_LinkedServers;', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Collect Linked Server Inventory', @name = 'Daily 9:45 PM', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 1, @freq_subday_interval = 0, @active_start_time = 214500;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Collect Linked Server Inventory', @server_name = '(local)';
GO

-- === DBAOps - Collect Maintenance Logs ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Collect Maintenance Logs')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Collect Maintenance Logs', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Collect Maintenance Logs', @enabled = 1, @description = 'Collects CommandLog data from all monitored SQL Servers to central repository.', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Collect Maintenance Logs', @step_name = 'Collect Logs', @step_id = 1, @subsystem = 'TSQL', @command = 'EXEC DBAOpsRepository.dbo.usp_CollectMaintenanceLogs @DaysBack = 7;', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Collect Maintenance Logs', @name = 'Every 4 Hours', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 8, @freq_subday_interval = 4, @active_start_time = 0;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Collect Maintenance Logs', @server_name = '(local)';
GO

-- === DBAOps - Collect Performance Baseline ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Collect Performance Baseline')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Collect Performance Baseline', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Collect Performance Baseline', @enabled = 1, @description = 'No description available.', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Collect Performance Baseline', @step_name = 'Collect Performance Baseline', @step_id = 1, @subsystem = 'TSQL', @command = 'EXEC ctl.usp_Collect_PerformanceBaseline;', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Collect Performance Baseline', @name = 'Daily at 3AM', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 1, @freq_subday_interval = 0, @active_start_time = 30000;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Collect Performance Baseline', @server_name = '(local)';
GO

-- === DBAOps â€“ Collect Performance Snapshots ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps â€“ Collect Performance Snapshots')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps â€“ Collect Performance Snapshots', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps â€“ Collect Performance Snapshots', @enabled = 1, @description = 'Runs the DBAOps PowerShell engine to collect CPU, memory, PLE, batch/sec, and connections from all SQL Servers based on A2 table.', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Collect Performance Snapshots', @step_name = 'Collect Performance Metrics', @step_id = 1, @subsystem = 'PowerShell', @command = 'powershell.exe -ExecutionPolicy Bypass -File "{{InstallPath}}\Scripts\Collect-PerformanceSnapshot.ps1"', @on_success_action = 1, @on_fail_action = 4;
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Collect Performance Snapshots', @step_name = 'Send Failure Alert', @step_id = 2, @subsystem = 'TSQL', @command = '
EXEC msdb.dbo.sp_send_dbmail
    @profile_name = ''DBAOpsProfile'',
    @recipients   = ''dbaops@yourdomain.com'',
    @subject      = ''*** SQL ALERT: Job Failure â€“ $(ESCAPE_NONE(JOBNAME)) ***'',
    @body         = ''SQL Agent detected a failure in job "$(ESCAPE_NONE(JOBNAME))" on server "$(ESCAPE_NONE(SRVR))".'',
    @body_format  = ''TEXT'';
', @on_success_action = 1, @on_fail_action = 1;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps â€“ Collect Performance Snapshots', @name = 'Every 5 Minutes', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 4, @freq_subday_interval = 5, @active_start_time = 0;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps â€“ Collect Performance Snapshots', @server_name = '(local)';
GO

-- === DBAOps - Collect Performance Telemetry ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Collect Performance Telemetry')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Collect Performance Telemetry', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Collect Performance Telemetry', @enabled = 1, @description = 'Collect CPU, memory, and I/O metrics from all servers', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Collect Performance Telemetry', @step_name = 'Execute', @step_id = 1, @subsystem = 'TSQL', @command = 'EXEC DBAOps.usp_CollectPerformanceTelemetry;', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Collect Performance Telemetry', @name = 'DBAOps - Collect Performance Telemetry Schedule', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 4, @freq_subday_interval = 5, @active_start_time = 0;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Collect Performance Telemetry', @server_name = '(local)';
GO

-- === DBAOps - Collect Permission Changes ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Collect Permission Changes')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Collect Permission Changes', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Collect Permission Changes', @enabled = 1, @description = 'No description available.', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Collect Permission Changes', @step_name = 'Collect Permission Changes', @step_id = 1, @subsystem = 'TSQL', @command = 'EXEC ctl.usp_Collect_PermissionChanges;', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Collect Permission Changes', @name = 'Every 1 Hour', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 8, @freq_subday_interval = 1, @active_start_time = 0;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Collect Permission Changes', @server_name = '(local)';
GO

-- === DBAOps - Collect Permissions ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Collect Permissions')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Collect Permissions', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Collect Permissions', @enabled = 1, @description = 'Collect server and database permissions from all servers', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Collect Permissions', @step_name = 'Execute', @step_id = 1, @subsystem = 'TSQL', @command = 'EXEC security.usp_CollectPermissions;', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Collect Permissions', @name = 'DBAOps - Collect Permissions Schedule', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 1, @freq_subday_interval = 0, @active_start_time = 50000;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Collect Permissions', @server_name = '(local)';
GO

-- === DBAOps - Collect Replication Latency ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Collect Replication Latency')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Collect Replication Latency', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Collect Replication Latency', @enabled = 1, @description = 'Collect replication latency metrics', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Collect Replication Latency', @step_name = 'Execute', @step_id = 1, @subsystem = 'TSQL', @command = 'EXEC DBAOpsRepository.replmon.usp_CollectReplicationLatency;', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Collect Replication Latency', @name = 'DBAOps - Collect Replication Latency Schedule', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 4, @freq_subday_interval = 5, @active_start_time = 0;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Collect Replication Latency', @server_name = '(local)';
GO

-- === DBAOps - Collect Server Alerts ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Collect Server Alerts')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Collect Server Alerts', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Collect Server Alerts', @enabled = 1, @description = 'Collects alerts and error log entries from all CMS-registered servers. Updates alerts.RecentAlerts table. Runs every 5 minutes.', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Collect Server Alerts', @step_name = 'Collect Alerts from CMS Servers', @step_id = 1, @subsystem = 'TSQL', @command = '
SET NOCOUNT ON;

DECLARE @ServerName NVARCHAR(128);
DECLARE @LinkedServer NVARCHAR(150);
DECLARE @SQL NVARCHAR(MAX);
DECLARE @Collected INT = 0;
DECLARE @Errors INT = 0;

-- Cursor through CMS servers (SOURCE OF TRUTH)
DECLARE server_cursor CURSOR LOCAL FAST_FORWARD FOR
    SELECT server_name
    FROM msdb.dbo.sysmanagement_shared_registered_servers_internal
    WHERE server_name NOT LIKE ''%\%''
      AND server_name <> @@SERVERNAME;

OPEN server_cursor;
FETCH NEXT FROM server_cursor INTO @ServerName;

WHILE @@FETCH_STATUS = 0
BEGIN
    SET @LinkedServer = ''DBAOps_Alert_'' + REPLACE(@ServerName, ''.'', ''_'');
    
    BEGIN TRY
        -- Drop if exists
        IF EXISTS (SELECT 1 FROM sys.servers WHERE name = @LinkedServer)
            EXEC sp_dropserver @LinkedServer, ''droplogins'';
        
        -- Create temp linked server with TrustServerCertificate
        EXEC sp_addlinkedserver 
            @server = @LinkedServer,
            @srvproduct = '''',
            @provider = ''MSOLEDBSQL19'',
            @datasrc = @ServerName,
            @provstr = ''TrustServerCertificate=yes'';
        
        EXEC sp_addlinkedsrvlogin @LinkedServer, ''True'';
        
        -- Collect alerts (errors from last 24 hours)
        SET @SQL = N''
        INSERT INTO alerts.RecentAlerts (ServerName, AlertTime, AlertType, AlertMessage, CollectedAt)
        SELECT TOP 100
            '''''' + @ServerName + '''''' AS ServerName,
            LogDate AS AlertTime,
            ''''Error'''' AS AlertType,
            LEFT(Text, 500) AS AlertMessage,
            GETDATE() AS CollectedAt
        FROM OPENQUERY(['' + @LinkedServer + ''], 
            ''''SELECT LogDate, Text FROM sys.dm_exec_errorlog WHERE LogDate > DATEADD(HOUR, -24, GETDATE()) AND Text LIKE ''''''''%Error%'''''''' ORDER BY LogDate DESC'''')
        '';
        
        BEGIN TRY
            EXEC sp_executesql @SQL;
            SET @Collected = @Collected + @@ROWCOUNT;
        END TRY
        BEGIN CATCH
        END CATCH
        
        -- Cleanup
        EXEC sp_dropserver @LinkedServer, ''droplogins'';
        
    END TRY
    BEGIN CATCH
        SET @Errors = @Errors + 1;
        -- Cleanup on error
        BEGIN TRY
            IF EXISTS (SELECT 1 FROM sys.servers WHERE name = @LinkedServer)
                EXEC sp_dropserver @LinkedServer, ''droplogins'';
        END TRY
        BEGIN CATCH END CATCH
    END CATCH
    
    FETCH NEXT FROM server_cursor INTO @ServerName;
END

CLOSE server_cursor;
DEALLOCATE server_cursor;

PRINT ''Alerts collected: '' + CAST(@Collected AS VARCHAR(10));
PRINT ''Servers with errors: '' + CAST(@Errors AS VARCHAR(10));
', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Collect Server Alerts', @name = 'Every 5 Minutes', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 4, @freq_subday_interval = 5, @active_start_time = 0;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Collect Server Alerts', @server_name = '(local)';
GO

-- === DBAOps - Collect Server Health ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Collect Server Health')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Collect Server Health', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Collect Server Health', @enabled = 1, @description = 'Collects health metrics (CPU, memory, disk, connections) from all CMS-registered servers. Runs every 5 minutes.', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Collect Server Health', @step_name = 'Execute Get-ServerHealth.ps1', @step_id = 1, @subsystem = 'CmdExec', @command = 'powershell.exe -ExecutionPolicy Bypass -File "{{InstallPath}}\PowerShell\Get-ServerHealth.ps1"', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Collect Server Health', @name = 'Every 5 Minutes', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 4, @freq_subday_interval = 5, @active_start_time = 0;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Collect Server Health', @server_name = '(local)';
GO

-- === DBAOps - Collect Server Inventory ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Collect Server Inventory')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Collect Server Inventory', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Collect Server Inventory', @enabled = 1, @description = 'Refresh server inventory from all linked servers', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Collect Server Inventory', @step_name = 'Execute', @step_id = 1, @subsystem = 'TSQL', @command = 'EXEC DBAOps.usp_CollectServerInventory;', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Collect Server Inventory', @name = 'DBAOps - Collect Server Inventory Schedule', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 1, @freq_subday_interval = 0, @active_start_time = 60000;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Collect Server Inventory', @server_name = '(local)';
GO

-- === DBAOps - Collect Service Accounts ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Collect Service Accounts')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Collect Service Accounts', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Collect Service Accounts', @enabled = 1, @description = 'Inventory SQL Server service accounts', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Collect Service Accounts', @step_name = 'Execute', @step_id = 1, @subsystem = 'TSQL', @command = 'EXEC security.usp_CollectServiceAccounts;', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Collect Service Accounts', @name = 'DBAOps - Collect Service Accounts Schedule', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 1, @freq_subday_interval = 0, @active_start_time = 50000;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Collect Service Accounts', @server_name = '(local)';
GO

-- === DBAOps - Collect SQL Agent Jobs ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Collect SQL Agent Jobs')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Collect SQL Agent Jobs', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Collect SQL Agent Jobs', @enabled = 1, @description = 'Collects SQL Agent job information from all CMS-registered servers. Updates jobs.SQLAgentJobs table. Runs every 15 minutes.', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Collect SQL Agent Jobs', @step_name = 'Execute Collect-SQLAgentJobs.ps1', @step_id = 1, @subsystem = 'PowerShell', @command = '& "{{InstallPath}}\PowerShell\Collect-SQLAgentJobs.ps1"', @on_success_action = 3, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Collect SQL Agent Jobs', @step_name = 'Update Job Statistics', @step_id = 2, @subsystem = 'TSQL', @command = '
-- Update job collection statistics
UPDATE DBAOpsRepository.config.CollectionStats
SET LastCollectionTime = GETDATE(),
    LastCollectionStatus = ''Success'',
    RecordsCollected = (SELECT COUNT(*) FROM DBAOpsRepository.jobs.SQLAgentJobs)
WHERE CollectionName = ''SQLAgentJobs'';

IF @@ROWCOUNT = 0
BEGIN
    INSERT INTO DBAOpsRepository.config.CollectionStats 
        (CollectionName, LastCollectionTime, LastCollectionStatus, RecordsCollected)
    VALUES (''SQLAgentJobs'', GETDATE(), ''Success'', 
        (SELECT COUNT(*) FROM DBAOpsRepository.jobs.SQLAgentJobs));
END
', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Collect SQL Agent Jobs', @name = 'Every 15 Minutes', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 4, @freq_subday_interval = 15, @active_start_time = 0;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Collect SQL Agent Jobs', @server_name = '(local)';
GO

-- === DBAOps â€“ Collect SQL Server Inventory ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps â€“ Collect SQL Server Inventory')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps â€“ Collect SQL Server Inventory', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps â€“ Collect SQL Server Inventory', @enabled = 1, @description = 'Runs Collect-ServerInventory.ps1 to populate the DBAOpsRepository inventory every hour.', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Collect SQL Server Inventory', @step_name = 'Collect Server Inventory', @step_id = 1, @subsystem = 'TSQL', @command = 'EXEC dbo.usp_CollectSQLServerInventory', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps â€“ Collect SQL Server Inventory', @name = 'Hourly Inventory Collector', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 8, @freq_subday_interval = 1, @active_start_time = 0;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps â€“ Collect SQL Server Inventory', @server_name = '(local)';
GO

-- === DBAOps - Collect SSRS Report Access ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Collect SSRS Report Access')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Collect SSRS Report Access', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Collect SSRS Report Access', @enabled = 1, @description = 'Collects SSRS report access logs. V2.2 FINAL with explicit parameters.', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Collect SSRS Report Access', @step_name = 'Run SSRS Audit Collection Script', @step_id = 1, @subsystem = 'PowerShell', @command = 'Set-Location "{{InstallPath}}\Scripts\ETL\Compliance"; .\Collect-SSRS-Audit.ps1 -CentralServer $env:COMPUTERNAME -CentralDatabase "DBAOpsRepository" -CollectionIntervalMinutes 15', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Collect SSRS Report Access', @name = 'Every 15 Minutes', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 4, @freq_subday_interval = 15, @active_start_time = 0;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Collect SSRS Report Access', @server_name = '(local)';
GO

-- === DBAOps - Collect Wait Stats ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Collect Wait Stats')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Collect Wait Stats', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Collect Wait Stats', @enabled = 1, @description = 'Collect wait statistics from all servers', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Collect Wait Stats', @step_name = 'Execute', @step_id = 1, @subsystem = 'TSQL', @command = 'EXEC DBAOps.usp_CollectWaitStats;', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Collect Wait Stats', @name = 'DBAOps - Collect Wait Stats Schedule', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 4, @freq_subday_interval = 15, @active_start_time = 0;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Collect Wait Stats', @server_name = '(local)';
GO

-- === DBAOps - Compliance Assessment ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Compliance Assessment')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Compliance Assessment', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Compliance Assessment', @enabled = 1, @description = 'Runs CJIS, NIST, STIG, DISA compliance assessment across all SQL Servers every 30 minutes', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Compliance Assessment', @step_name = 'Run Compliance Assessment', @step_id = 1, @subsystem = 'PowerShell', @command = '& "{{InstallPath}}\Scripts\Collect-ComplianceAssessment.ps1"', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Compliance Assessment', @name = 'Every 30 Minutes', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 4, @freq_subday_interval = 30, @active_start_time = 0;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Compliance Assessment', @server_name = '(local)';
GO

-- === DBAOps - Compliance Evidence Collector ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Compliance Evidence Collector')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Compliance Evidence Collector', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Compliance Evidence Collector', @enabled = 1, @description = 'Collects compliance evidence for CJIS, NIST controls across all CMS servers.', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Compliance Evidence Collector', @step_name = 'CJIS 5.4.1.1 - Auditing', @step_id = 1, @subsystem = 'TSQL', @command = '
DECLARE @ServerName NVARCHAR(128) = @@SERVERNAME;
DECLARE @Evidence NVARCHAR(MAX);
DECLARE @Status NVARCHAR(50);

-- Check if SQL Audit is enabled
SELECT @Evidence = (
    SELECT name, is_state_enabled, type_desc, on_failure_desc
    FROM sys.server_audits
    FOR JSON PATH
);

IF @Evidence IS NOT NULL AND @Evidence != ''[]''
    SET @Status = ''Pass''
ELSE
BEGIN
    SET @Status = ''Warning'';
    SET @Evidence = ''{"warning": "No SQL Server audits configured"}'';
END

EXEC compliance.usp_CollectEvidence
    @Framework = ''CJIS'',
    @ControlID = ''5.4.1.1'',
    @ServerName = @ServerName,
    @EvidenceType = ''Query'',
    @EvidenceData = @Evidence,
    @ComplianceStatus = @Status,
    @Findings = ''SQL Server Audit configuration check'';

PRINT ''CJIS 5.4.1.1 evidence collected'';', @on_success_action = 3, @on_fail_action = 3;
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Compliance Evidence Collector', @step_name = 'CJIS 5.6.1 - Encryption', @step_id = 2, @subsystem = 'TSQL', @command = '
DECLARE @ServerName NVARCHAR(128) = @@SERVERNAME;
DECLARE @Evidence NVARCHAR(MAX);
DECLARE @Status NVARCHAR(50) = ''Pass'';

-- Check TDE status and encrypted connections
SELECT @Evidence = (
    SELECT 
        d.name AS DatabaseName,
        d.is_encrypted AS TDE_Enabled,
        k.encryptor_type AS EncryptorType
    FROM sys.databases d
    LEFT JOIN sys.dm_database_encryption_keys k ON d.database_id = k.database_id
    WHERE d.database_id > 4
    FOR JSON PATH
);

-- Check Force Encryption
DECLARE @ForceEncrypt INT;
EXEC master.dbo.xp_instance_regread N''HKEY_LOCAL_MACHINE'',
    N''SOFTWARE\Microsoft\Microsoft SQL Server\MSSQLServer\SuperSocketNetLib'',
    N''ForceEncryption'', @ForceEncrypt OUTPUT;

IF @ForceEncrypt != 1
    SET @Status = ''Warning'';

SET @Evidence = CONCAT(''{"ForceEncryption": '', ISNULL(@ForceEncrypt, 0), '', "Databases": '', ISNULL(@Evidence, ''[]''), ''}'');

EXEC compliance.usp_CollectEvidence
    @Framework = ''CJIS'',
    @ControlID = ''5.6.1'',
    @ServerName = @ServerName,
    @EvidenceType = ''Query'',
    @EvidenceData = @Evidence,
    @ComplianceStatus = @Status,
    @Findings = ''Encryption configuration check'';

PRINT ''CJIS 5.6.1 evidence collected'';', @on_success_action = 3, @on_fail_action = 3;
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Compliance Evidence Collector', @step_name = 'CJIS 5.5.2 - Access Control', @step_id = 3, @subsystem = 'TSQL', @command = '
DECLARE @ServerName NVARCHAR(128) = @@SERVERNAME;
DECLARE @Evidence NVARCHAR(MAX);
DECLARE @Status NVARCHAR(50) = ''Pass'';

-- Check sysadmin members
SELECT @Evidence = (
    SELECT 
        p.name AS LoginName,
        p.type_desc AS LoginType,
        p.is_disabled AS IsDisabled
    FROM sys.server_principals p
    JOIN sys.server_role_members rm ON p.principal_id = rm.member_principal_id
    JOIN sys.server_principals r ON rm.role_principal_id = r.principal_id
    WHERE r.name = ''sysadmin''
    FOR JSON PATH
);

-- Flag if SA account is enabled
IF EXISTS (SELECT 1 FROM sys.server_principals WHERE name = ''sa'' AND is_disabled = 0)
    SET @Status = ''Warning'';

EXEC compliance.usp_CollectEvidence
    @Framework = ''CJIS'',
    @ControlID = ''5.5.2'',
    @ServerName = @ServerName,
    @EvidenceType = ''Query'',
    @EvidenceData = @Evidence,
    @ComplianceStatus = @Status,
    @Findings = ''Sysadmin role membership audit'';

PRINT ''CJIS 5.5.2 evidence collected'';', @on_success_action = 3, @on_fail_action = 3;
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Compliance Evidence Collector', @step_name = 'CJIS 5.10.1.2 - Patch Management', @step_id = 4, @subsystem = 'TSQL', @command = '
DECLARE @ServerName NVARCHAR(128) = @@SERVERNAME;
DECLARE @Evidence NVARCHAR(MAX);
DECLARE @Status NVARCHAR(50) = ''Pass'';

-- Get current patch level
SELECT @Evidence = (
    SELECT 
        SERVERPROPERTY(''ProductVersion'') AS SQLVersion,
        SERVERPROPERTY(''ProductLevel'') AS ServicePack,
        SERVERPROPERTY(''ProductUpdateLevel'') AS CumulativeUpdate,
        SERVERPROPERTY(''Edition'') AS Edition
    FOR JSON PATH, WITHOUT_ARRAY_WRAPPER
);

-- Check if within 90 days of latest CU (simplified check)
DECLARE @BuildDate DATETIME;
SELECT @BuildDate = create_date FROM sys.databases WHERE name = ''tempdb'';

IF @BuildDate < DATEADD(DAY, -90, GETDATE())
    SET @Status = ''Warning'';

EXEC compliance.usp_CollectEvidence
    @Framework = ''CJIS'',
    @ControlID = ''5.10.1.2'',
    @ServerName = @ServerName,
    @EvidenceType = ''Query'',
    @EvidenceData = @Evidence,
    @ComplianceStatus = @Status,
    @Findings = ''SQL Server patch level verification'';

PRINT ''CJIS 5.10.1.2 evidence collected'';', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Compliance Evidence Collector', @name = 'Daily0600_Compliance', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 1, @freq_subday_interval = 0, @active_start_time = 60000;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Compliance Evidence Collector', @server_name = '(local)';
GO

-- === DBAOps - Correlation Engine ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Correlation Engine')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Correlation Engine', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Correlation Engine', @enabled = 1, @description = 'Correlates alerts into incidents, checks escalations, cleans up fingerprints.', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Correlation Engine', @step_name = 'Correlate Alerts', @step_id = 1, @subsystem = 'TSQL', @command = 'EXEC correlation.usp_CorrelateAlerts @ProcessMinutes = 60;', @on_success_action = 3, @on_fail_action = 3;
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Correlation Engine', @step_name = 'Check Escalations', @step_id = 2, @subsystem = 'TSQL', @command = '
DECLARE @CritCnt INT;
SELECT @CritCnt = COUNT(*) FROM correlation.vw_ActiveIncidents 
WHERE Severity = 1 AND Status = ''Open'' AND AcknowledgedBy IS NULL AND AgeMinutes >= 5;
IF @CritCnt > 0 PRINT CONCAT(''ESCALATION: '', @CritCnt, '' critical incidents unacknowledged'');', @on_success_action = 3, @on_fail_action = 3;
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Correlation Engine', @step_name = 'Cleanup Stale Fingerprints', @step_id = 3, @subsystem = 'TSQL', @command = 'UPDATE correlation.Fingerprints SET IsActive = 0 WHERE LastSeenDate < DATEADD(DAY, -7, GETDATE()) AND IsActive = 1;', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Correlation Engine', @name = 'Every5Min_Correlation', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 4, @freq_subday_interval = 5, @active_start_time = 0;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Correlation Engine', @server_name = '(local)';
GO

-- === DBAOps â€“ Critical Health Alert ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps â€“ Critical Health Alert')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps â€“ Critical Health Alert', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps â€“ Critical Health Alert', @enabled = 1, @description = 'Checks for critical health issues every 5 min and sends alert. CJIS/NIST/DISA compliant. Author: RHOYLLE INNOVATION EMPIRE LLC', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Critical Health Alert', @step_name = 'Check Critical Compliance', @step_id = 1, @subsystem = 'TSQL', @command = '
-- Only send if there are critical issues
DECLARE @CritCount INT;
SELECT @CritCount = COUNT(*)
FROM (
    SELECT h.ServerName
    FROM (
        SELECT *, ROW_NUMBER() OVER (PARTITION BY ServerName ORDER BY CaptureTime DESC) AS rn
        FROM DBAOpsRepository.metrics.FACT_ServerHealth WHERE CaptureTime >= DATEADD(HOUR, -1, GETDATE())
    ) h
    LEFT JOIN (
        SELECT ServerName, MAX(100 - FreePercent) AS DiskUsed
        FROM DBAOpsRepository.fact.DiskSpaceMetrics WHERE CaptureDate >= DATEADD(DAY, -1, GETDATE())
        GROUP BY ServerName
    ) d ON h.ServerName = d.ServerName
    WHERE h.rn = 1 AND (
        h.CPU_Utilization > 90 OR
        (h.Memory_UsedMB * 100.0 / NULLIF(h.Memory_TotalMB, 0)) > 90 OR
        h.Memory_PLE < 300 OR
        h.BlockingSessions > 5 OR
        ISNULL(d.DiskUsed, 0) > 85
    )
) x;

IF @CritCount > 0
    EXEC DBAOpsRepository.alert.usp_CriticalServerAlert @SendEmail = 1;
ELSE
    PRINT ''No critical issues found'';
', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps â€“ Critical Health Alert', @name = 'DBAOps_CriticalAlert_Every5Min', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 4, @freq_subday_interval = 5, @active_start_time = 0;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps â€“ Critical Health Alert', @server_name = '(local)';
GO

-- === DBAOps â€“ Critical Infrastructure Report ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps â€“ Critical Infrastructure Report')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps â€“ Critical Infrastructure Report', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps â€“ Critical Infrastructure Report', @enabled = 1, @description = 'Daily comprehensive infrastructure health report with all metrics. Author: RHOYLLE INNOVATION EMPIRE LLC', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Critical Infrastructure Report', @step_name = 'Collect All Infrastructure Data', @step_id = 1, @subsystem = 'TSQL', @command = '
-- Collect all metrics
EXEC inventory.usp_Collect_FileGrowthConfig_AllServers;
EXEC security.usp_Collect_SecurityInventory_AllServers;
EXEC inventory.usp_Collect_DatabaseInventory_AllServers;
', @on_success_action = 3, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Critical Infrastructure Report', @step_name = 'Send Daily Infrastructure Report', @step_id = 2, @subsystem = 'TSQL', @command = 'EXEC alert.usp_CriticalInfrastructureReport;', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps â€“ Critical Infrastructure Report', @name = 'Daily at 8 AM', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 1, @freq_subday_interval = 0, @active_start_time = 80000;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps â€“ Critical Infrastructure Report', @server_name = '(local)';
GO

-- === DBAOps - Critical Monitoring ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Critical Monitoring')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Critical Monitoring', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Critical Monitoring', @enabled = 1, @description = 'No description available.', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Critical Monitoring', @step_name = 'Run DBAOps Launcher', @step_id = 1, @subsystem = 'PowerShell', @command = 'powershell.exe -NoProfile -ExecutionPolicy Bypass -File "{{InstallPath}}\Scripts\DBAOps-MonitoringLauncher-v1.0.ps1"', @on_success_action = 1, @on_fail_action = 4;
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Critical Monitoring', @step_name = 'Send Failure Alert', @step_id = 2, @subsystem = 'TSQL', @command = '
EXEC msdb.dbo.sp_send_dbmail
    @profile_name = ''DBAOpsProfile'',
    @recipients   = ''dbaops@yourdomain.com'',
    @subject      = ''*** SQL ALERT: Job Failure â€“ $(ESCAPE_NONE(JOBNAME)) ***'',
    @body         = ''SQL Agent detected a failure in job "$(ESCAPE_NONE(JOBNAME))" on server "$(ESCAPE_NONE(SRVR))".'',
    @body_format  = ''TEXT'';
', @on_success_action = 1, @on_fail_action = 1;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Critical Monitoring', @name = 'DBAOps - Critical Schedule', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 4, @freq_subday_interval = 15, @active_start_time = 0;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Critical Monitoring', @server_name = '(local)';
GO

-- === DBAOps - CU Deployment Engine ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - CU Deployment Engine')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - CU Deployment Engine', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - CU Deployment Engine', @enabled = 1, @description = 'Automated SQL Server CU deployment engine. Processes approved deployments from the queue.', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - CU Deployment Engine', @step_name = 'Run CU Deployment', @step_id = 1, @subsystem = 'CmdExec', @command = 'powershell.exe -ExecutionPolicy Bypass -File "C:\DBAOps\Scripts\Deploy-CU.ps1" -DBAOpsServer $env:COMPUTERNAME -DBAOpsDatabase "DBAOpsRepository"', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - CU Deployment Engine', @name = 'NonProd Thursday 10PM', @freq_type = 8, @freq_interval = 16, @freq_subday_type = 1, @freq_subday_interval = 0, @active_start_time = 220000;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - CU Deployment Engine', @server_name = '(local)';
GO

-- === DBAOps - Daily Architecture Status ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Daily Architecture Status')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Daily Architecture Status', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Daily Architecture Status', @enabled = 1, @description = 'Generates and emails one-sentence DBAOps architecture health status', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Daily Architecture Status', @step_name = 'Generate Status', @step_id = 1, @subsystem = 'TSQL', @command = '
DECLARE @msg NVARCHAR(1000);
EXEC Assessment.usp_GenerateDailyStatus;
', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Daily Architecture Status', @name = 'DBAOps Daily Status 6AM', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 1, @freq_subday_interval = 0, @active_start_time = 60000;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Daily Architecture Status', @server_name = '(local)';
GO

-- === DBAOps â€“ Daily Audit Collector and Notification ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps â€“ Daily Audit Collector and Notification')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps â€“ Daily Audit Collector and Notification', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps â€“ Daily Audit Collector and Notification', @enabled = 1, @description = 'Collects audit events from all SQL Servers in A2 and sends daily audit notifications.', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Daily Audit Collector and Notification', @step_name = '1 - Collect SQL Audit Logs via PowerShell', @step_id = 1, @subsystem = 'PowerShell', @command = 'powershell.exe -NoProfile -ExecutionPolicy Bypass -File "{{InstallPath}}\Scripts\Collect_SQL_AuditLogs.ps1"', @on_success_action = 3, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Daily Audit Collector and Notification', @step_name = '2 - Send Daily Audit Email Report', @step_id = 2, @subsystem = 'TSQL', @command = 'EXEC audit.usp_SendAuditEmail;', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Daily Audit Collector and Notification', @step_name = '1 - Collect SQL Audit Logs', @step_id = 3, @subsystem = 'PowerShell', @command = 'powershell.exe -ExecutionPolicy Bypass -File "{{InstallPath}}\Scripts\DBAOps_AuditCollector.ps1"', @on_success_action = 3, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Daily Audit Collector and Notification', @step_name = '2 - Build Daily Summary', @step_id = 4, @subsystem = 'TSQL', @command = 'EXEC audit.usp_Audit_ServerSummary;', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Daily Audit Collector and Notification', @step_name = '3 - Retention Cleanup', @step_id = 5, @subsystem = 'TSQL', @command = 'EXEC audit.usp_Audit_CleanUp;', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Daily Audit Collector and Notification', @step_name = '4 - Send Daily Audit Email', @step_id = 6, @subsystem = 'TSQL', @command = 'EXEC audit.usp_SendAuditEmail;', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps â€“ Daily Audit Collector and Notification', @name = 'DBAOps â€“ Daily Audit Schedule', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 1, @freq_subday_interval = 0, @active_start_time = 60000;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps â€“ Daily Audit Collector and Notification', @server_name = '(local)';
GO

-- === DBAOps - Daily Cleanup ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Daily Cleanup')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Daily Cleanup', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Daily Cleanup', @enabled = 1, @description = 'Daily maintenance: purges old data, updates statistics, rebuilds indexes on DBAOpsRepository. Runs daily at 2:00 AM.', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Daily Cleanup', @step_name = 'Purge Old Data', @step_id = 1, @subsystem = 'TSQL', @command = '
/*
    DBAOps Daily Cleanup - Purge Old Data
    Retention Policies:
    - Alerts: 7 days
    - Job History: 30 days
    - Metrics: 90 days
    - Fact tables: 365 days
*/
SET NOCOUNT ON;

DECLARE @PurgeDate7 DATETIME = DATEADD(DAY, -7, GETDATE());
DECLARE @PurgeDate30 DATETIME = DATEADD(DAY, -30, GETDATE());
DECLARE @PurgeDate90 DATETIME = DATEADD(DAY, -90, GETDATE());
DECLARE @PurgeDate365 DATETIME = DATEADD(DAY, -365, GETDATE());
DECLARE @RowsDeleted INT;

-- Purge old alerts (7 days)
DELETE FROM alerts.RecentAlerts WHERE CollectedAt < @PurgeDate7;
SET @RowsDeleted = @@ROWCOUNT;
PRINT ''Purged '' + CAST(@RowsDeleted AS VARCHAR) + '' old alerts'';

-- Purge old job history snapshots (30 days)
IF OBJECT_ID(''jobs.SQLAgentJobHistory'', ''U'') IS NOT NULL
BEGIN
    DELETE FROM jobs.SQLAgentJobHistory WHERE CollectedAt < @PurgeDate30;
    SET @RowsDeleted = @@ROWCOUNT;
    PRINT ''Purged '' + CAST(@RowsDeleted AS VARCHAR) + '' old job history records'';
END

-- Purge old metrics (90 days)
IF OBJECT_ID(''metrics.ServerMetrics'', ''U'') IS NOT NULL
BEGIN
    DELETE FROM metrics.ServerMetrics WHERE CollectedAt < @PurgeDate90;
    SET @RowsDeleted = @@ROWCOUNT;
    PRINT ''Purged '' + CAST(@RowsDeleted AS VARCHAR) + '' old metrics records'';
END

-- Purge old fact data (365 days)
IF OBJECT_ID(''fact.DailyServerStats'', ''U'') IS NOT NULL
BEGIN
    DELETE FROM fact.DailyServerStats WHERE StatDate < @PurgeDate365;
    SET @RowsDeleted = @@ROWCOUNT;
    PRINT ''Purged '' + CAST(@RowsDeleted AS VARCHAR) + '' old daily stats'';
END

-- Cleanup log files older than 30 days
-- This will be handled by PowerShell in next step

PRINT ''Data purge completed at '' + CONVERT(VARCHAR, GETDATE(), 120);
', @on_success_action = 3, @on_fail_action = 3;
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Daily Cleanup', @step_name = 'Update Statistics', @step_id = 2, @subsystem = 'TSQL', @command = '
-- Update statistics on key tables
USE DBAOpsRepository;

UPDATE STATISTICS config.ServerInventory;
UPDATE STATISTICS jobs.SQLAgentJobs;
UPDATE STATISTICS alerts.RecentAlerts;
UPDATE STATISTICS Patching.ServerPatchStatus;

PRINT ''Statistics updated at '' + CONVERT(VARCHAR, GETDATE(), 120);
', @on_success_action = 3, @on_fail_action = 3;
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Daily Cleanup', @step_name = 'Cleanup Log Files', @step_id = 3, @subsystem = 'PowerShell', @command = '& "{{InstallPath}}\PowerShell\DBAOps-DailyCleanup.ps1"', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Daily Cleanup', @name = 'Daily at 2AM', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 1, @freq_subday_interval = 0, @active_start_time = 20000;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Daily Cleanup', @server_name = '(local)';
GO

-- === DBAOps - Daily CMS Status Report ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Daily CMS Status Report')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Daily CMS Status Report', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Daily CMS Status Report', @enabled = 1, @description = 'Daily CMS status check and HTML email report at 8:00 AM. Compares CMS registered servers with DBAOps inventory and identifies any discrepancies.', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Daily CMS Status Report', @step_name = 'Run CMS Status Report', @step_id = 1, @subsystem = 'TSQL', @command = 'EXEC DBAOpsRepository.report.usp_CMSStatusReport @SendEmail = 1, @EmailRecipients = ''dbaops@yourdomain.com'';', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Daily CMS Status Report', @name = 'Daily 8AM', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 1, @freq_subday_interval = 0, @active_start_time = 80000;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Daily CMS Status Report', @server_name = '(local)';
GO

-- === DBAOps - Daily Dashboard ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Daily Dashboard')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Daily Dashboard', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Daily Dashboard', @enabled = 0, @description = 'Generates full SQL Server dashboard (inventory, compliance, trends).', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Daily Dashboard', @step_name = 'Generate Dashboard', @step_id = 1, @subsystem = 'PowerShell', @command = 'powershell.exe -File "{{InstallPath}}\Scripts\Generate-Dashboard.ps1"', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Daily Dashboard', @name = 'DBAOps_Daily_Dashboard_6AM', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 1, @freq_subday_interval = 0, @active_start_time = 600;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Daily Dashboard', @server_name = '(local)';
GO

-- === DBAOps - Daily Environment Audit Report ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Daily Environment Audit Report')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Daily Environment Audit Report', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Daily Environment Audit Report', @enabled = 1, @description = 'Runs comprehensive DBAOps environment audit daily at 7:00 AM and emails HTML report.', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Daily Environment Audit Report', @step_name = 'Run Daily Audit and Email Report', @step_id = 1, @subsystem = 'TSQL', @command = '
EXEC dbo.usp_DBAOps_EnvironmentAudit
    @EmailReport = 1,
    @EmailRecipients = N''dbaops@yourdomain.com'',
    @EmailProfile = N''DBAOpsProfile'',
    @OutputToTable = 1,
    @PrintHTML = 0,
    @Debug = 0;
', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Daily Environment Audit Report', @name = 'Daily at 7:00 AM', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 1, @freq_subday_interval = 0, @active_start_time = 70000;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Daily Environment Audit Report', @server_name = '(local)';
GO

-- === DBAOps â€“ Daily Health Report ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps â€“ Daily Health Report')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps â€“ Daily Health Report', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps â€“ Daily Health Report', @enabled = 1, @description = 'Sends the daily consolidated SQL Server health dashboard', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Daily Health Report', @step_name = 'Send Email', @step_id = 1, @subsystem = 'TSQL', @command = 'EXEC DBAOpsRepository.dbo.usp_Send_DBAOps_DailyHealthReport;', @on_success_action = 1, @on_fail_action = 4;
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Daily Health Report', @step_name = 'Send Failure Alert', @step_id = 2, @subsystem = 'TSQL', @command = '
EXEC msdb.dbo.sp_send_dbmail
    @profile_name = ''DBAOpsProfile'',
    @recipients   = ''dbaops@yourdomain.com'',
    @subject      = ''*** SQL ALERT: Job Failure â€“ $(ESCAPE_NONE(JOBNAME)) ***'',
    @body         = ''SQL Agent detected a failure in job "$(ESCAPE_NONE(JOBNAME))" on server "$(ESCAPE_NONE(SRVR))".'',
    @body_format  = ''TEXT'';
', @on_success_action = 1, @on_fail_action = 1;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps â€“ Daily Health Report', @name = 'Daily 7AM', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 1, @freq_subday_interval = 0, @active_start_time = 70000;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps â€“ Daily Health Report', @server_name = '(local)';
GO

-- === DBAOps - Daily Infrastructure Report ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Daily Infrastructure Report')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Daily Infrastructure Report', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Daily Infrastructure Report', @enabled = 1, @description = 'Daily comprehensive infrastructure health report', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Daily Infrastructure Report', @step_name = 'Generate Report', @step_id = 1, @subsystem = 'TSQL', @command = 'EXEC DBAOpsRepository.report.usp_DailyInfrastructureReport @SendEmail = 1;', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Daily Infrastructure Report', @name = 'Daily_7AM_Report', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 1, @freq_subday_interval = 0, @active_start_time = 70000;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Daily Infrastructure Report', @server_name = '(local)';
GO

-- === DBAOps - Daily Inventory Report ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Daily Inventory Report')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Daily Inventory Report', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Daily Inventory Report', @enabled = 1, @description = 'DBAOps: Daily database inventory report with users, logins, permissions, and change detection alerts. Runs daily at 7:00 AM. Author: RHOYLLE INNOVATION EMPIRE LLC', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Daily Inventory Report', @step_name = 'Generate and Send Daily Inventory Report', @step_id = 1, @subsystem = 'TSQL', @command = '
-- ============================================================================
-- DBAOps Daily Inventory Report with Change Detection
-- ============================================================================
SET NOCOUNT ON;

DECLARE @ServerCount INT;
DECLARE @UserDBCount INT;
DECLARE @TotalSizeGB DECIMAL(18,2);
DECLARE @LastUpdate DATETIME;
DECLARE @ProdDBCount INT;
DECLARE @NonProdDBCount INT;
DECLARE @TotalLogins INT;
DECLARE @TotalUsers INT;
DECLARE @TotalPermissions INT;
DECLARE @NewDatabases INT = 0;
DECLARE @DroppedDatabases INT = 0;
DECLARE @PermissionChanges INT = 0;
DECLARE @NewLogins INT = 0;
DECLARE @ObjectChanges INT = 0;
DECLARE @Subject NVARCHAR(500);
DECLARE @TableHTML NVARCHAR(MAX);
DECLARE @AlertSection NVARCHAR(MAX) = '''';
DECLARE @HasAlerts BIT = 0;

-- Get USER database counts
SELECT 
    @ServerCount = COUNT(DISTINCT di.ServerName),
    @UserDBCount = COUNT(DISTINCT di.DatabaseName),
    @TotalSizeGB = CAST(SUM(di.SizeMB) / 1024.0 AS DECIMAL(18,2)),
    @LastUpdate = MAX(di.CaptureTime)
FROM dbo.fact_DatabaseInventory di
WHERE di.DatabaseName NOT IN (''master'', ''model'', ''msdb'', ''tempdb'', 
                               ''ReportServer'', ''ReportServerTempDB'', 
                               ''distribution'', ''SSISDB'', ''DBAOpsRepository'')
  AND di.CaptureTime >= DATEADD(DAY, -1, GETDATE());

-- PROD count
SELECT @ProdDBCount = COUNT(DISTINCT di.DatabaseName)
FROM dbo.fact_DatabaseInventory di
JOIN config.ServerInventory si ON di.ServerName = si.ServerName
WHERE di.DatabaseName NOT IN (''master'', ''model'', ''msdb'', ''tempdb'')
  AND di.CaptureTime >= DATEADD(DAY, -1, GETDATE())
  AND si.Environment = ''PROD'';

-- NONPROD count
SELECT @NonProdDBCount = COUNT(DISTINCT di.DatabaseName)
FROM dbo.fact_DatabaseInventory di
JOIN config.ServerInventory si ON di.ServerName = si.ServerName
WHERE di.DatabaseName NOT IN (''master'', ''model'', ''msdb'', ''tempdb'')
  AND di.CaptureTime >= DATEADD(DAY, -1, GETDATE())
  AND si.Environment = ''NONPROD'';

-- Logins & Users
SELECT @TotalLogins = COUNT(DISTINCT PrincipalName) FROM security.ServerPermissions WHERE CollectedDate >= DATEADD(DAY, -1, GETDATE());
SELECT @TotalUsers = COUNT(DISTINCT PrincipalName) FROM security.DatabasePermissions WHERE CollectedDate >= DATEADD(DAY, -1, GETDATE());
SELECT @TotalPermissions = (SELECT COUNT(*) FROM security.ServerPermissions WHERE CollectedDate >= DATEADD(DAY, -1, GETDATE())) +
                           (SELECT COUNT(*) FROM security.DatabasePermissions WHERE CollectedDate >= DATEADD(DAY, -1, GETDATE()));

-- Detect new databases
SELECT @NewDatabases = COUNT(*)
FROM (
    SELECT DISTINCT ServerName, DatabaseName FROM dbo.fact_DatabaseInventory
    WHERE CaptureTime >= DATEADD(DAY, -1, GETDATE()) AND DatabaseName NOT IN (''master'', ''model'', ''msdb'', ''tempdb'')
    EXCEPT
    SELECT DISTINCT ServerName, DatabaseName FROM dbo.fact_DatabaseInventory
    WHERE CaptureTime >= DATEADD(DAY, -2, GETDATE()) AND CaptureTime < DATEADD(DAY, -1, GETDATE())
      AND DatabaseName NOT IN (''master'', ''model'', ''msdb'', ''tempdb'')
) AS NewDBs;

-- Permission changes
IF OBJECT_ID(''security.PermissionDrift'', ''U'') IS NOT NULL
    SELECT @PermissionChanges = COUNT(*) FROM security.PermissionDrift WHERE DetectedDate >= DATEADD(DAY, -1, GETDATE());

-- DDL changes
IF OBJECT_ID(''fact.DDLAuditEvents'', ''U'') IS NOT NULL
    SELECT @ObjectChanges = COUNT(*) FROM fact.DDLAuditEvents WHERE EventTime >= DATEADD(DAY, -1, GETDATE());

-- Set alerts flag
IF @NewDatabases > 0 OR @PermissionChanges > 0 OR @ObjectChanges > 0
    SET @HasAlerts = 1;

-- Build alert section
IF @HasAlerts = 1
    SET @AlertSection = N''<div style="background-color: #fff3cd; border: 2px solid #ffc107; padding: 15px; margin: 20px 0; border-radius: 8px;">
        <h3 style="color: #856404;">âš ï¸ CHANGES DETECTED</h3>
        <p>ðŸ†• New Databases: '' + CAST(@NewDatabases AS NVARCHAR(10)) + ''</p>
        <p>ðŸ” Permission Changes: '' + CAST(@PermissionChanges AS NVARCHAR(10)) + ''</p>
        <p>ðŸ“ DDL Changes: '' + CAST(@ObjectChanges AS NVARCHAR(10)) + ''</p>
    </div>'';
ELSE
    SET @AlertSection = N''<div style="background-color: #d4edda; border: 2px solid #28a745; padding: 15px; margin: 20px 0; border-radius: 8px;">
        <h3 style="color: #155724;">âœ… No Changes Detected</h3>
    </div>'';

-- Build HTML
SET @TableHTML = N''<html><head><style>
body{font-family:Segoe UI,Arial;font-size:14px}
.header{background:linear-gradient(135deg,#1a5276,#2980b9);color:white;padding:20px;border-radius:10px 10px 0 0}
.card{background:#f8f9fa;padding:15px;border-radius:8px;text-align:center;margin:10px;display:inline-block;min-width:120px}
.card .num{font-size:32px;font-weight:bold;color:#1a5276}
.prod{background:#27ae60;color:white;padding:8px 15px;border-radius:20px;margin:5px}
.nonprod{background:#f39c12;color:white;padding:8px 15px;border-radius:20px;margin:5px}
table{border-collapse:collapse;width:100%}th{background:#1a5276;color:white;padding:10px}td{border:1px solid #ddd;padding:8px}
</style></head><body>
<div class="header"><h1>ðŸ“Š Daily Database Inventory Report</h1><p>'' + CONVERT(NVARCHAR(20), GETDATE(), 120) + ''</p></div>
<div style="padding:20px">
<div class="card"><div class="num">'' + CAST(@UserDBCount AS NVARCHAR(10)) + ''</div><div>User DBs</div></div>
<div class="card"><div class="num">'' + CAST(@ServerCount AS NVARCHAR(10)) + ''</div><div>Servers</div></div>
<div class="card"><div class="num">'' + CAST(@TotalSizeGB AS NVARCHAR(20)) + ''</div><div>Size (GB)</div></div>
<div class="card"><div class="num">'' + CAST(ISNULL(@TotalLogins,0) AS NVARCHAR(10)) + ''</div><div>Logins</div></div>
<div class="card"><div class="num">'' + CAST(ISNULL(@TotalUsers,0) AS NVARCHAR(10)) + ''</div><div>Users</div></div>
<br/><br/>
<span class="prod">'' + CAST(ISNULL(@ProdDBCount,0) AS NVARCHAR(10)) + '' PROD</span>
<span class="nonprod">'' + CAST(ISNULL(@NonProdDBCount,0) AS NVARCHAR(10)) + '' NONPROD</span>
'' + @AlertSection + ''
</div>
<div style="background:#f8f9fa;padding:15px;font-size:11px;color:#666">
DBAOps Enterprise™ Framework | RHOYLLE INNOVATION EMPIRE LLC
</div></body></html>'';

-- Set subject
IF @HasAlerts = 1
    SET @Subject = N''âš ï¸ DBAOps Daily: '' + CAST(@UserDBCount AS NVARCHAR(10)) + N'' DBs | CHANGES DETECTED'';
ELSE
    SET @Subject = N''âœ… DBAOps Daily: '' + CAST(@UserDBCount AS NVARCHAR(10)) + N'' User DBs ('' + CAST(ISNULL(@ProdDBCount,0) AS NVARCHAR(10)) + N'' PROD)'';

-- Send email
EXEC msdb.dbo.sp_send_dbmail
    @profile_name = ''DBAOpsProfile'',
    @recipients = ''dbaops@yourdomain.com'',
    @subject = @Subject,
    @body = @TableHTML,
    @body_format = ''HTML'';
', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Daily Inventory Report', @name = 'Daily at 7:00 AM', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 1, @freq_subday_interval = 0, @active_start_time = 70000;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Daily Inventory Report', @server_name = '(local)';
GO

-- === DBAOps â€“ Daily Inventory Snapshot ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps â€“ Daily Inventory Snapshot')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps â€“ Daily Inventory Snapshot', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps â€“ Daily Inventory Snapshot', @enabled = 1, @description = 'Daily collection of all server, instance, database, and OS metadata', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Daily Inventory Snapshot', @step_name = 'Run Inventory', @step_id = 1, @subsystem = 'PowerShell', @command = '& "{{InstallPath}}\Collect-DailyInventory.ps1"', @on_success_action = 1, @on_fail_action = 4;
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Daily Inventory Snapshot', @step_name = 'Send Failure Alert', @step_id = 2, @subsystem = 'TSQL', @command = '
EXEC msdb.dbo.sp_send_dbmail
    @profile_name = ''DBAOpsProfile'',
    @recipients   = ''dbaops@yourdomain.com'',
    @subject      = ''*** SQL ALERT: Job Failure â€“ $(ESCAPE_NONE(JOBNAME)) ***'',
    @body         = ''SQL Agent detected a failure in job "$(ESCAPE_NONE(JOBNAME))" on server "$(ESCAPE_NONE(SRVR))".'',
    @body_format  = ''TEXT'';
', @on_success_action = 1, @on_fail_action = 1;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps â€“ Daily Inventory Snapshot', @name = 'Daily at 1 AM', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 1, @freq_subday_interval = 0, @active_start_time = 10000;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps â€“ Daily Inventory Snapshot', @server_name = '(local)';
GO

-- === DBAOps - Daily Monitoring ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Daily Monitoring')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Daily Monitoring', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Daily Monitoring', @enabled = 1, @description = 'No description available.', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Daily Monitoring', @step_name = 'Run DBAOps Launcher', @step_id = 1, @subsystem = 'PowerShell', @command = 'powershell.exe -NoProfile -ExecutionPolicy Bypass -File "{{InstallPath}}\Scripts\DBAOps-MonitoringLauncher-v1.0.ps1"', @on_success_action = 1, @on_fail_action = 4;
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Daily Monitoring', @step_name = 'Send Failure Alert', @step_id = 2, @subsystem = 'TSQL', @command = '
EXEC msdb.dbo.sp_send_dbmail
    @profile_name = ''DBAOpsProfile'',
    @recipients   = ''dbaops@yourdomain.com'',
    @subject      = ''*** SQL ALERT: Job Failure â€“ $(ESCAPE_NONE(JOBNAME)) ***'',
    @body         = ''SQL Agent detected a failure in job "$(ESCAPE_NONE(JOBNAME))" on server "$(ESCAPE_NONE(SRVR))".'',
    @body_format  = ''TEXT'';
', @on_success_action = 1, @on_fail_action = 1;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Daily Monitoring', @name = 'DBAOps - Daily Schedule', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 1, @freq_subday_interval = 0, @active_start_time = 20000;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Daily Monitoring', @server_name = '(local)';
GO

-- === DBAOps - Daily Security Compliance Report ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Daily Security Compliance Report')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Daily Security Compliance Report', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Daily Security Compliance Report', @enabled = 1, @description = 'Daily comprehensive security and compliance report - CJIS, NIST, DISA standards', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Daily Security Compliance Report', @step_name = 'Generate Daily Report', @step_id = 1, @subsystem = 'TSQL', @command = 'EXEC DBAOpsRepository.report.usp_UnifiedSecurityComplianceReport @ReportType = ''DAILY'', @SendEmail = 1;', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Daily Security Compliance Report', @name = 'Daily_6AM_SecurityCompliance', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 1, @freq_subday_interval = 0, @active_start_time = 60000;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Daily Security Compliance Report', @server_name = '(local)';
GO

-- === DBAOps - Daily Security Report ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Daily Security Report')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Daily Security Report', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Daily Security Report', @enabled = 1, @description = 'Daily comprehensive security audit report - Login failures, permission changes, drift detection', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Daily Security Report', @step_name = 'Generate Security Report', @step_id = 1, @subsystem = 'TSQL', @command = 'EXEC DBAOpsRepository.report.usp_DailySecurityReport @SendEmail = 1;', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Daily Security Report', @name = 'Daily_6AM_SecurityReport', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 1, @freq_subday_interval = 0, @active_start_time = 60000;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Daily Security Report', @server_name = '(local)';
GO

-- === DBAOps - Daily SQL Patch Compliance Collector ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Daily SQL Patch Compliance Collector')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Daily SQL Patch Compliance Collector', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Daily SQL Patch Compliance Collector', @enabled = 1, @description = 'DBAOps Monitoring and Compliance Framework - Collects SQL Server patch info and Tanium tag status daily. Author: RHOYLLE INNOVATION EMPIRE LLC', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Daily SQL Patch Compliance Collector', @step_name = 'Collect Patch Info', @step_id = 1, @subsystem = 'CmdExec', @command = 'powershell.exe -NoProfile -ExecutionPolicy Bypass -File "C:\DBAOpsScripts\CollectPatchInfo.ps1"', @on_success_action = 3, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Daily SQL Patch Compliance Collector', @step_name = 'Collect Tanium Tags', @step_id = 2, @subsystem = 'TSQL', @command = 'EXEC Patching.usp_CollectTaniumTagStatus;', @on_success_action = 3, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Daily SQL Patch Compliance Collector', @step_name = 'Update Compliance Status', @step_id = 3, @subsystem = 'TSQL', @command = 'EXEC Patching.usp_UpdateComplianceStatus; EXEC Patching.usp_UpdateTaniumCompliance;', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Daily SQL Patch Compliance Collector', @name = 'Daily 6AM - Patch & Tanium Collection', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 1, @freq_subday_interval = 0, @active_start_time = 60000;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Daily SQL Patch Compliance Collector', @server_name = '(local)';
GO

-- === DBAOps â€“ Daily Summary Email ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps â€“ Daily Summary Email')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps â€“ Daily Summary Email', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps â€“ Daily Summary Email', @enabled = 1, @description = 'Sends the full DBAOps daily summary report', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Daily Summary Email', @step_name = 'Send Daily Summary', @step_id = 1, @subsystem = 'TSQL', @command = '
-- Generate the summary
EXEC dbo.usp_GenerateDailySummary;

-- Send the email report
DECLARE @Today DATE = CAST(GETDATE() AS DATE);
DECLARE @Subject NVARCHAR(200) = ''DBAOps Hourly Performance Summary - '' + CONVERT(VARCHAR, GETDATE(), 120);
DECLARE @Body NVARCHAR(MAX);

SET @Body = ''<html><body>
<h2>DBAOps Performance Summary Report</h2>
<p>Generated: '' + CONVERT(VARCHAR, GETDATE(), 120) + ''</p>

<h3>Alert Summary</h3>
<table border="1" cellpadding="5" cellspacing="0">
<tr style="background-color:#4472C4;color:white;">
<th>Date</th><th>Total</th><th>High</th><th>Medium</th><th>Low</th><th>Servers</th>
</tr>'';

SELECT @Body = @Body + ''<tr><td>'' + CONVERT(VARCHAR, SummaryDate) + ''</td><td>'' + CAST(TotalAlerts AS VARCHAR) + ''</td><td>'' + CAST(HighAlerts AS VARCHAR) + ''</td><td>'' + CAST(MediumAlerts AS VARCHAR) + ''</td><td>'' + CAST(LowAlerts AS VARCHAR) + ''</td><td>'' + CAST(UniqueServers AS VARCHAR) + ''</td></tr>''
FROM dbo.fact_DailyAlertSummary
WHERE SummaryDate = @Today;

SET @Body = @Body + ''</table>

<h3>Server Performance Summary</h3>
<table border="1" cellpadding="5" cellspacing="0">
<tr style="background-color:#4472C4;color:white;">
<th>Server</th><th>Avg CPU %</th><th>Max CPU %</th><th>Avg Memory %</th><th>Max Memory %</th><th>Batch Requests</th><th>Page Life Exp</th>
</tr>'';

SELECT @Body = @Body + ''<tr><td>'' + ServerName + ''</td><td>'' + CAST(AvgCPUPercent AS VARCHAR) + ''</td><td>'' + CAST(MaxCPUPercent AS VARCHAR) + ''</td><td>'' + CAST(ISNULL(AvgMemoryPercent,0) AS VARCHAR) + ''</td><td>'' + CAST(ISNULL(MaxMemoryPercent,0) AS VARCHAR) + ''</td><td>'' + FORMAT(TotalBatchRequests, ''N0'') + ''</td><td>'' + FORMAT(PageLifeExpectancy, ''N0'') + ''</td></tr>''
FROM dbo.fact_DailyPerformanceSummary
WHERE SummaryDate = @Today;

SET @Body = @Body + ''</table>
</body></html>'';

EXEC msdb.dbo.sp_send_dbmail
    @profile_name = ''DBAOpsProfile'',
    @recipients = ''dbaops@yourdomain.com'',
    @subject = @Subject,
    @body = @Body,
    @body_format = ''HTML'';
', @on_success_action = 1, @on_fail_action = 4;
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Daily Summary Email', @step_name = 'Send Failure Alert', @step_id = 2, @subsystem = 'TSQL', @command = '
EXEC msdb.dbo.sp_send_dbmail
    @profile_name = ''DBAOpsProfile'',
    @recipients   = ''dbaops@yourdomain.com'',
    @subject      = ''*** SQL ALERT: Job Failure â€“ $(ESCAPE_NONE(JOBNAME)) ***'',
    @body         = ''SQL Agent detected a failure in job "$(ESCAPE_NONE(JOBNAME))" on server "$(ESCAPE_NONE(SRVR))".'',
    @body_format  = ''TEXT'';
', @on_success_action = 1, @on_fail_action = 1;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps â€“ Daily Summary Email', @name = 'Daily Summary â€“ 7AM', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 1, @freq_subday_interval = 0, @active_start_time = 70000;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps â€“ Daily Summary Email', @server_name = '(local)';
GO

-- === DBAOps â€“ Daily Trend Capture ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps â€“ Daily Trend Capture')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps â€“ Daily Trend Capture', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps â€“ Daily Trend Capture', @enabled = 1, @description = 'No description available.', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Daily Trend Capture', @step_name = 'Capture Trend', @step_id = 1, @subsystem = 'TSQL', @command = 'EXEC ctl.usp_CaptureServerInventoryHistory', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Daily Trend Capture', @step_name = 'Run PowerShell Collector', @step_id = 2, @subsystem = 'PowerShell', @command = '{{InstallPath}}\Scripts\Collect-DailyTrend.ps1', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps â€“ Daily Trend Capture', @name = 'Daily at 11PM', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 1, @freq_subday_interval = 0, @active_start_time = 230000;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps â€“ Daily Trend Capture', @server_name = '(local)';
GO

-- === DBAOps - Dashboard Data Refresh ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Dashboard Data Refresh')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Dashboard Data Refresh', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Dashboard Data Refresh', @enabled = 1, @description = 'Collects dashboard data from all CMS-registered servers and generates data.json for the web dashboard. Runs every 5 minutes.', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Dashboard Data Refresh', @step_name = 'Execute Get-DBAOpsDashboardData.ps1', @step_id = 1, @subsystem = 'CmdExec', @command = 'powershell.exe -ExecutionPolicy Bypass -File {{InstallPath}}\PowerShell\Update-DBAOpsDashboard.ps1', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Dashboard Data Refresh', @name = 'Every 5 Minutes', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 4, @freq_subday_interval = 5, @active_start_time = 200;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Dashboard Data Refresh', @server_name = '(local)';
GO

-- === DBAOps - Dashboard Health Watchdog ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Dashboard Health Watchdog')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Dashboard Health Watchdog', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Dashboard Health Watchdog', @enabled = 1, @description = 'Self-healing: detects empty/stale/corrupt data.json and auto-remediates every 2 min', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Dashboard Health Watchdog', @step_name = 'Check and Remediate', @step_id = 1, @subsystem = 'PowerShell', @command = '& "{{InstallPath}}\Scripts\Watch-DashboardHealth.ps1"', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Dashboard Health Watchdog', @name = 'Every 2 Minutes', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 4, @freq_subday_interval = 2, @active_start_time = 0;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Dashboard Health Watchdog', @server_name = '(local)';
GO

-- === DBAOps - Dashboard Inventory Refresh ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Dashboard Inventory Refresh')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Dashboard Inventory Refresh', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Dashboard Inventory Refresh', @enabled = 1, @description = 'Collects SQL Server inventory from CMS and populates dashboard tables (dbo.dim_Servers, inventory.dim_ServerBuilds)', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Dashboard Inventory Refresh', @step_name = 'Run PowerShell Collection Script', @step_id = 1, @subsystem = 'PowerShell', @command = '{{InstallPath}}\WebDashboard\Update-DashboardInventory.ps1', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Dashboard Inventory Refresh', @name = 'Hourly at :15', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 8, @freq_subday_interval = 1, @active_start_time = 1500;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Dashboard Inventory Refresh', @server_name = '(local)';
GO

-- === DBAOps â€“ Dashboard Maintenance ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps â€“ Dashboard Maintenance')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps â€“ Dashboard Maintenance', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps â€“ Dashboard Maintenance', @enabled = 1, @description = 'Purges old dashboard data and refreshes rollup views', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Dashboard Maintenance', @step_name = 'Purge Dashboard', @step_id = 1, @subsystem = 'TSQL', @command = 'EXEC DBAOpsRepository.dbo.usp_DBAOps_PurgeDashboard;', @on_success_action = 1, @on_fail_action = 4;
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Dashboard Maintenance', @step_name = 'Send Failure Alert', @step_id = 2, @subsystem = 'TSQL', @command = '
EXEC msdb.dbo.sp_send_dbmail
    @profile_name = ''DBAOpsProfile'',
    @recipients   = ''dbaops@yourdomain.com'',
    @subject      = ''*** SQL ALERT: Job Failure â€“ $(ESCAPE_NONE(JOBNAME)) ***'',
    @body         = ''SQL Agent detected a failure in job "$(ESCAPE_NONE(JOBNAME))" on server "$(ESCAPE_NONE(SRVR))".'',
    @body_format  = ''TEXT'';
', @on_success_action = 1, @on_fail_action = 1;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps â€“ Dashboard Maintenance', @name = 'DBAOps Dashboard Daily Midnight', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 1, @freq_subday_interval = 0, @active_start_time = 100;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps â€“ Dashboard Maintenance', @server_name = '(local)';
GO

-- === DBAOps - Data Retention Cleanup ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Data Retention Cleanup')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Data Retention Cleanup', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Data Retention Cleanup', @enabled = 1, @description = 'Cleans up old data from DBAOps tables based on retention policy. Part of DBAOps monitoring platform.', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Data Retention Cleanup', @step_name = 'Clean Up Old Data', @step_id = 1, @subsystem = 'TSQL', @command = '
USE DBAOpsRepository;

DECLARE @RetentionDays INT = 90;
DECLARE @ShortRetentionDays INT = 30;
DECLARE @RowsDeleted INT;

-- Performance data (30 days)
DELETE FROM perf.WaitStatistics WHERE CollectedAt < DATEADD(DAY, -@ShortRetentionDays, GETDATE());
SET @RowsDeleted = @@ROWCOUNT; IF @RowsDeleted > 0 PRINT ''Deleted '' + CAST(@RowsDeleted AS VARCHAR) + '' rows from perf.WaitStatistics'';

DELETE FROM perf.TopQueries WHERE CollectedAt < DATEADD(DAY, -@ShortRetentionDays, GETDATE());
SET @RowsDeleted = @@ROWCOUNT; IF @RowsDeleted > 0 PRINT ''Deleted '' + CAST(@RowsDeleted AS VARCHAR) + '' rows from perf.TopQueries'';

-- Capacity data (90 days)
DELETE FROM capacity.DiskSpaceHistory WHERE CollectedAt < DATEADD(DAY, -@RetentionDays, GETDATE());
SET @RowsDeleted = @@ROWCOUNT; IF @RowsDeleted > 0 PRINT ''Deleted '' + CAST(@RowsDeleted AS VARCHAR) + '' rows from capacity.DiskSpaceHistory'';

DELETE FROM capacity.DatabaseSizeHistory WHERE CollectedAt < DATEADD(DAY, -@RetentionDays, GETDATE());
SET @RowsDeleted = @@ROWCOUNT; IF @RowsDeleted > 0 PRINT ''Deleted '' + CAST(@RowsDeleted AS VARCHAR) + '' rows from capacity.DatabaseSizeHistory'';

-- Backup history (90 days) - using bkp schema
DELETE FROM bkp.BackupHistory WHERE CollectedAt < DATEADD(DAY, -@RetentionDays, GETDATE());
SET @RowsDeleted = @@ROWCOUNT; IF @RowsDeleted > 0 PRINT ''Deleted '' + CAST(@RowsDeleted AS VARCHAR) + '' rows from bkp.BackupHistory'';

-- Alert history (180 days)
DELETE FROM alert.AlertHistory WHERE ArchivedAt < DATEADD(DAY, -180, GETDATE());
SET @RowsDeleted = @@ROWCOUNT; IF @RowsDeleted > 0 PRINT ''Deleted '' + CAST(@RowsDeleted AS VARCHAR) + '' rows from alert.AlertHistory'';

-- Replication history (30 days)
DELETE FROM repl.ReplicationLatencyHistory WHERE CollectedAt < DATEADD(DAY, -@ShortRetentionDays, GETDATE());
SET @RowsDeleted = @@ROWCOUNT; IF @RowsDeleted > 0 PRINT ''Deleted '' + CAST(@RowsDeleted AS VARCHAR) + '' rows from repl.ReplicationLatencyHistory'';

-- Job history (90 days)
DELETE FROM dbo.JobDurationHistory WHERE CollectedAt < DATEADD(DAY, -@RetentionDays, GETDATE());
SET @RowsDeleted = @@ROWCOUNT; IF @RowsDeleted > 0 PRINT ''Deleted '' + CAST(@RowsDeleted AS VARCHAR) + '' rows from dbo.JobDurationHistory'';

PRINT ''Data retention cleanup completed successfully'';', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Data Retention Cleanup', @name = 'Weekly on Sunday at 3 AM', @freq_type = 8, @freq_interval = 1, @freq_subday_type = 1, @freq_subday_interval = 0, @active_start_time = 30000;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Data Retention Cleanup', @server_name = '(local)';
GO

-- === DBAOps - Database Change Tracking and Notification ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Database Change Tracking and Notification')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Database Change Tracking and Notification', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Database Change Tracking and Notification', @enabled = 1, @description = 'DBAOps Enterprise™ Framework | Author: RHOYLLE INNOVATION EMPIRE LLC (JB)

Monitors ALL SQL Servers daily for database changes:
- New databases added
- Databases removed/dropped
- Owner changes
- Recovery model changes

Sends HTML email notifications when changes are detected.
Schedule: Daily at 6:00 AM', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Database Change Tracking and Notification', @step_name = 'Execute Database Change Tracking', @step_id = 1, @subsystem = 'TSQL', @command = '
/*
================================================================================
   DBAOps Database Change Tracking | Author: JB
================================================================================
*/
DECLARE @Recipients NVARCHAR(MAX) = ''dbaops@yourdomain.com'';
DECLARE @MailProfile NVARCHAR(256) = ''DBAOpsProfile'';

EXEC [DBAOpsRepository].[inventory].[usp_DatabaseChangeTrackingJob_JB]
    @Recipients = @Recipients,
    @MailProfile = @MailProfile,
    @Debug = 0;
', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Database Change Tracking and Notification', @name = 'Daily at 6AM - JB', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 1, @freq_subday_interval = 0, @active_start_time = 60000;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Database Change Tracking and Notification', @server_name = '(local)';
GO

-- === DBAOps - Detect Permission Drift ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Detect Permission Drift')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Detect Permission Drift', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Detect Permission Drift', @enabled = 1, @description = 'Detect permission changes from baseline', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Detect Permission Drift', @step_name = 'Execute', @step_id = 1, @subsystem = 'TSQL', @command = 'EXEC DBAOpsRepository.security.usp_DetectPermissionDrift;', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Detect Permission Drift', @name = 'DBAOps - Detect Permission Drift Schedule', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 1, @freq_subday_interval = 0, @active_start_time = 53000;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Detect Permission Drift', @server_name = '(local)';
GO

-- === DBAOps â€“ Disk Space Alert ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps â€“ Disk Space Alert')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps â€“ Disk Space Alert', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps â€“ Disk Space Alert', @enabled = 1, @description = 'Checks disk free space and triggers critical alerts.', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Disk Space Alert', @step_name = 'Collect Disk Space', @step_id = 1, @subsystem = 'TSQL', @command = 'EXEC dbo.usp_CollectDiskSpace_AllServers @Debug = 0;', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Disk Space Alert', @step_name = 'Send Failure Alert', @step_id = 2, @subsystem = 'TSQL', @command = '
EXEC msdb.dbo.sp_send_dbmail
    @profile_name = ''DBAOpsProfile'',
    @recipients   = ''dbaops@yourdomain.com'',
    @subject      = ''*** SQL ALERT: Job Failure â€“ $(ESCAPE_NONE(JOBNAME)) ***'',
    @body         = ''SQL Agent detected a failure in job "$(ESCAPE_NONE(JOBNAME))" on server "$(ESCAPE_NONE(SRVR))".'',
    @body_format  = ''TEXT'';
', @on_success_action = 1, @on_fail_action = 1;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps â€“ Disk Space Alert', @name = 'Every 10 Minutes', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 4, @freq_subday_interval = 10, @active_start_time = 0;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps â€“ Disk Space Alert', @server_name = '(local)';
GO

-- === DBAOps â€“ Disk Space Collector ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps â€“ Disk Space Collector')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps â€“ Disk Space Collector', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps â€“ Disk Space Collector', @enabled = 1, @description = 'No description available.', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Disk Space Collector', @step_name = 'Collect Disk Space Info', @step_id = 1, @subsystem = 'TSQL', @command = 'EXEC DBAOpsRepository.ctl.usp_Collect_DiskSpaceCompliance;', @on_success_action = 1, @on_fail_action = 4;
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Disk Space Collector', @step_name = 'Send Failure Alert', @step_id = 2, @subsystem = 'TSQL', @command = '
EXEC msdb.dbo.sp_send_dbmail
    @profile_name = ''DBAOpsProfile'',
    @recipients   = ''dbaops@yourdomain.com'',
    @subject      = ''*** SQL ALERT: Job Failure â€“ $(ESCAPE_NONE(JOBNAME)) ***'',
    @body         = ''SQL Agent detected a failure in job "$(ESCAPE_NONE(JOBNAME))" on server "$(ESCAPE_NONE(SRVR))".'',
    @body_format  = ''TEXT'';
', @on_success_action = 1, @on_fail_action = 1;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps â€“ Disk Space Collector', @name = 'DBAOps â€“ Every 1 Hour', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 8, @freq_subday_interval = 1, @active_start_time = 0;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps â€“ Disk Space Collector', @server_name = '(local)';
GO

-- === DBAOps - Disk Space Smart Alert ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Disk Space Smart Alert')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Disk Space Smart Alert', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Disk Space Smart Alert', @enabled = 1, @description = 'Smart disk space alerting with variable intervals based on severity. Critical=5min, Warning=15min, Caution=30min.', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Disk Space Smart Alert', @step_name = 'Run Smart Disk Alert', @step_id = 1, @subsystem = 'TSQL', @command = 'EXEC alert.usp_DiskSpaceSmartAlert @SendEmail = 1, @Debug = 0;', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Disk Space Smart Alert', @name = 'Every 5 Minutes', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 4, @freq_subday_interval = 5, @active_start_time = 0;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Disk Space Smart Alert', @server_name = '(local)';
GO

-- === DBAOps â€“ Disk Space Threshold Alert ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps â€“ Disk Space Threshold Alert')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps â€“ Disk Space Threshold Alert', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps â€“ Disk Space Threshold Alert', @enabled = 1, @description = 'Monitors disk space with threshold-based alerting. 50%=60min, 75%=30min, 85%=15min, 95%=5min. Author: RHOYLLE INNOVATION EMPIRE LLC', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Disk Space Threshold Alert', @step_name = 'Check Disk Space Thresholds', @step_id = 1, @subsystem = 'TSQL', @command = 'EXEC alert.usp_DiskSpaceThresholdAlert;', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps â€“ Disk Space Threshold Alert', @name = 'DBAOps_DiskSpace_Every_5_Min', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 4, @freq_subday_interval = 5, @active_start_time = 0;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps â€“ Disk Space Threshold Alert', @server_name = '(local)';
GO

-- === DBAOps â€“ DiskSpace Job History Cleanup ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps â€“ DiskSpace Job History Cleanup')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps â€“ DiskSpace Job History Cleanup', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps â€“ DiskSpace Job History Cleanup', @enabled = 1, @description = 'Purges job history for the DiskSpace collector.', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ DiskSpace Job History Cleanup', @step_name = 'Purge History', @step_id = 1, @subsystem = 'TSQL', @command = '
        DECLARE @job_id UNIQUEIDENTIFIER =
            (SELECT job_id FROM msdb.dbo.sysjobs WHERE name = ''DBAOps â€“ Collect Disk Space Metrics'');

        EXEC msdb.dbo.sp_purge_jobhistory @job_id = @job_id;
        ', @on_success_action = 1, @on_fail_action = 4;
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ DiskSpace Job History Cleanup', @step_name = 'Send Failure Alert', @step_id = 2, @subsystem = 'TSQL', @command = '
EXEC msdb.dbo.sp_send_dbmail
    @profile_name = ''DBAOpsProfile'',
    @recipients   = ''dbaops@yourdomain.com'',
    @subject      = ''*** SQL ALERT: Job Failure â€“ $(ESCAPE_NONE(JOBNAME)) ***'',
    @body         = ''SQL Agent detected a failure in job "$(ESCAPE_NONE(JOBNAME))" on server "$(ESCAPE_NONE(SRVR))".'',
    @body_format  = ''TEXT'';
', @on_success_action = 1, @on_fail_action = 1;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps â€“ DiskSpace Job History Cleanup', @name = 'DBAOps â€“ DiskSpace Cleanup Daily', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 1, @freq_subday_interval = 0, @active_start_time = 20000;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps â€“ DiskSpace Job History Cleanup', @server_name = '(local)';
GO

-- === DBAOps â€“ DiskSpace Metrics Maintenance ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps â€“ DiskSpace Metrics Maintenance')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps â€“ DiskSpace Metrics Maintenance', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps â€“ DiskSpace Metrics Maintenance', @enabled = 1, @description = 'Performs dedupe, retention, and index maintenance for DiskSpaceMetrics.', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ DiskSpace Metrics Maintenance', @step_name = 'Cleanup Metrics', @step_id = 1, @subsystem = 'TSQL', @command = 'EXEC ctl.usp_Maintain_DiskSpaceMetrics;', @on_success_action = 1, @on_fail_action = 4;
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ DiskSpace Metrics Maintenance', @step_name = 'Send Failure Alert', @step_id = 2, @subsystem = 'TSQL', @command = '
EXEC msdb.dbo.sp_send_dbmail
    @profile_name = ''DBAOpsProfile'',
    @recipients   = ''dbaops@yourdomain.com'',
    @subject      = ''*** SQL ALERT: Job Failure â€“ $(ESCAPE_NONE(JOBNAME)) ***'',
    @body         = ''SQL Agent detected a failure in job "$(ESCAPE_NONE(JOBNAME))" on server "$(ESCAPE_NONE(SRVR))".'',
    @body_format  = ''TEXT'';
', @on_success_action = 1, @on_fail_action = 1;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps â€“ DiskSpace Metrics Maintenance', @name = 'DBAOps â€“ Daily 1 AM', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 1, @freq_subday_interval = 0, @active_start_time = 10000;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps â€“ DiskSpace Metrics Maintenance', @server_name = '(local)';
GO

-- === DBAOps - Enterprise Collector ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Enterprise Collector')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Enterprise Collector', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Enterprise Collector', @enabled = 1, @description = 'Collects enterprise metrics: Performance, Capacity, Backup, Security, Replication, Jobs. Part of DBAOps monitoring platform.', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Enterprise Collector', @step_name = 'Run Enterprise Collector', @step_id = 1, @subsystem = 'TSQL', @command = 'EXEC DBAOpsRepository.dbo.usp_DBAOps_EnterpriseCollector;', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Enterprise Collector', @name = 'Every 15 minutes', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 4, @freq_subday_interval = 15, @active_start_time = 0;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Enterprise Collector', @server_name = '(local)';
GO

-- === DBAOps â€“ ETL Orchestrator ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps â€“ ETL Orchestrator')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps â€“ ETL Orchestrator', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps â€“ ETL Orchestrator', @enabled = 1, @description = 'No description available.', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ ETL Orchestrator', @step_name = 'Backup', @step_id = 1, @subsystem = 'TSQL', @command = 'EXEC ctl.usp_Load_BackupCompliance;', @on_success_action = 3, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ ETL Orchestrator', @step_name = 'Repository', @step_id = 2, @subsystem = 'TSQL', @command = 'EXEC ctl.usp_Load_RepositoryStatus;', @on_success_action = 3, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ ETL Orchestrator', @step_name = 'Forecast', @step_id = 3, @subsystem = 'TSQL', @command = 'EXEC metrics.usp_UpdateForecastSimple;', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps â€“ ETL Orchestrator', @name = 'Every 30 Minutes', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 4, @freq_subday_interval = 30, @active_start_time = 0;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps â€“ ETL Orchestrator', @server_name = '(local)';
GO

-- === DBAOps â€“ FACT AutoHeal ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps â€“ FACT AutoHeal')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps â€“ FACT AutoHeal', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps â€“ FACT AutoHeal', @enabled = 1, @description = 'Runs FACT validation and autoheal pipeline', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ FACT AutoHeal', @step_name = 'Run FACT AutoHeal', @step_id = 1, @subsystem = 'TSQL', @command = 'EXEC ctl.usp_Fact_AutoHeal_All;', @on_success_action = 1, @on_fail_action = 4;
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ FACT AutoHeal', @step_name = 'Send Failure Alert', @step_id = 2, @subsystem = 'TSQL', @command = '
EXEC msdb.dbo.sp_send_dbmail
    @profile_name = ''DBAOpsProfile'',
    @recipients   = ''dbaops@yourdomain.com'',
    @subject      = ''*** SQL ALERT: Job Failure â€“ $(ESCAPE_NONE(JOBNAME)) ***'',
    @body         = ''SQL Agent detected a failure in job "$(ESCAPE_NONE(JOBNAME))" on server "$(ESCAPE_NONE(SRVR))".'',
    @body_format  = ''TEXT'';
', @on_success_action = 1, @on_fail_action = 1;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps â€“ FACT AutoHeal', @name = 'Daily_705AM_FACT_AutoHeal', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 1, @freq_subday_interval = 0, @active_start_time = 70500;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps â€“ FACT AutoHeal', @server_name = '(local)';
GO

-- === DBAOps â€“ FACT Daily Report ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps â€“ FACT Daily Report')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps â€“ FACT Daily Report', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps â€“ FACT Daily Report', @enabled = 1, @description = 'Sends the DBAOps Daily Summary Email', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ FACT Daily Report', @step_name = 'Run Daily FACT Summary', @step_id = 1, @subsystem = 'TSQL', @command = 'EXEC DBAOpsRepository.meta.usp_Fact_Report_Daily;', @on_success_action = 1, @on_fail_action = 4;
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ FACT Daily Report', @step_name = 'Send Failure Alert', @step_id = 2, @subsystem = 'TSQL', @command = '
EXEC msdb.dbo.sp_send_dbmail
    @profile_name = ''DBAOpsProfile'',
    @recipients   = ''dbaops@yourdomain.com'',
    @subject      = ''*** SQL ALERT: Job Failure â€“ $(ESCAPE_NONE(JOBNAME)) ***'',
    @body         = ''SQL Agent detected a failure in job "$(ESCAPE_NONE(JOBNAME))" on server "$(ESCAPE_NONE(SRVR))".'',
    @body_format  = ''TEXT'';
', @on_success_action = 1, @on_fail_action = 1;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps â€“ FACT Daily Report', @name = 'DBAOps FACT Daily 7AM', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 1, @freq_subday_interval = 0, @active_start_time = 70000;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps â€“ FACT Daily Report', @server_name = '(local)';
GO

-- === DBAOps â€“ FACT Data Validator ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps â€“ FACT Data Validator')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps â€“ FACT Data Validator', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps â€“ FACT Data Validator', @enabled = 1, @description = 'Runs FACT validation & auto-heal every 15 minutes', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ FACT Data Validator', @step_name = 'Validate FACT Tables', @step_id = 1, @subsystem = 'TSQL', @command = 'EXEC DBAOpsRepository.ctl.usp_Fact_AutoHeal_All;', @on_success_action = 1, @on_fail_action = 4;
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ FACT Data Validator', @step_name = 'Send Failure Alert', @step_id = 2, @subsystem = 'TSQL', @command = '
EXEC msdb.dbo.sp_send_dbmail
    @profile_name = ''DBAOpsProfile'',
    @recipients   = ''dbaops@yourdomain.com'',
    @subject      = ''*** SQL ALERT: Job Failure â€“ $(ESCAPE_NONE(JOBNAME)) ***'',
    @body         = ''SQL Agent detected a failure in job "$(ESCAPE_NONE(JOBNAME))" on server "$(ESCAPE_NONE(SRVR))".'',
    @body_format  = ''TEXT'';
', @on_success_action = 1, @on_fail_action = 1;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps â€“ FACT Data Validator', @name = 'Daily at 4AM', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 1, @freq_subday_interval = 0, @active_start_time = 40000;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps â€“ FACT Data Validator', @server_name = '(local)';
GO

-- === DBAOps â€“ File Growth Compliance Monitor ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps â€“ File Growth Compliance Monitor')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps â€“ File Growth Compliance Monitor', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps â€“ File Growth Compliance Monitor', @enabled = 1, @description = 'Monitors file growth compliance and sends CRITICAL alert for percentage-based growth. Author: RHOYLLE INNOVATION EMPIRE LLC', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ File Growth Compliance Monitor', @step_name = 'Collect File Growth Config', @step_id = 1, @subsystem = 'TSQL', @command = 'EXEC inventory.usp_Collect_FileGrowthConfig_AllServers;', @on_success_action = 3, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ File Growth Compliance Monitor', @step_name = 'Send Alert if Non-Compliant', @step_id = 2, @subsystem = 'TSQL', @command = 'EXEC alert.usp_FileGrowthComplianceAlert;', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps â€“ File Growth Compliance Monitor', @name = 'Daily at 7 AM', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 1, @freq_subday_interval = 0, @active_start_time = 70000;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps â€“ File Growth Compliance Monitor', @server_name = '(local)';
GO

-- === DBAOps - Forecast Storage ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Forecast Storage')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Forecast Storage', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Forecast Storage', @enabled = 1, @description = 'Generate storage capacity forecasts', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Forecast Storage', @step_name = 'Execute', @step_id = 1, @subsystem = 'TSQL', @command = 'EXEC capacity.usp_ForecastStorage;', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Forecast Storage', @name = 'Daily at 3AM - Forecast Storage', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 1, @freq_subday_interval = 0, @active_start_time = 30000;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Forecast Storage', @server_name = '(local)';
GO

-- === DBAOps - Framework Health Check ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Framework Health Check')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Framework Health Check', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Framework Health Check', @enabled = 1, @description = 'DBAOps: Monitors framework health and sends alerts for failures', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Framework Health Check', @step_name = 'Check Framework Health', @step_id = 1, @subsystem = 'TSQL', @command = '
EXEC dbo.usp_Monitor_JobHealth @SendEmail = 0;

-- Log framework status
DECLARE @FailedJobs INT, @TotalServers INT, @TotalDatabases INT;

SELECT @FailedJobs = COUNT(*) FROM DBAOpsRepository.dbo.vw_FailedJobs_Last24Hours;
SELECT @TotalServers = COUNT(*) FROM DBAOpsRepository.config.ServerInventory WHERE IsActive = 1;

IF @FailedJobs = 0
    PRINT ''DBAOps Enterprise™ Framework Health: OK - '' + CAST(@TotalServers AS VARCHAR) + '' servers monitored''
ELSE
    PRINT ''DBAOps Enterprise™ Framework Health: '' + CAST(@FailedJobs AS VARCHAR) + '' failed jobs detected''
', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Framework Health Check', @name = 'Every 30 Minutes', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 4, @freq_subday_interval = 30, @active_start_time = 0;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Framework Health Check', @server_name = '(local)';
GO

-- === DBAOps - Framework Health Monitor ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Framework Health Monitor')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Framework Health Monitor', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Framework Health Monitor', @enabled = 1, @description = 'Run framework self-health check', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Framework Health Monitor', @step_name = 'Execute', @step_id = 1, @subsystem = 'TSQL', @command = 'EXEC FrameworkHealth.usp_RunHealthCheck;', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Framework Health Monitor', @name = 'DBAOps - Framework Health Monitor Schedule', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 8, @freq_subday_interval = 1, @active_start_time = 0;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Framework Health Monitor', @server_name = '(local)';
GO

-- === DBAOps - Generate Dashboard Data ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Generate Dashboard Data')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Generate Dashboard Data', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Generate Dashboard Data', @enabled = 0, @description = 'Generates the data.json file for the DBAOps dashboard', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Generate Dashboard Data', @step_name = 'Run PowerShell Generation', @step_id = 1, @subsystem = 'CmdExec', @command = 'powershell.exe -ExecutionPolicy Bypass -File "{{InstallPath}}\PowerShell\Get-DBAOpsDashboardData.ps1"', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Generate Dashboard Data', @name = 'Hourly (offset)', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 8, @freq_subday_interval = 1, @active_start_time = 500;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Generate Dashboard Data', @server_name = '(local)';
GO

-- === DBAOps - Generate Health Report ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Generate Health Report')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Generate Health Report', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Generate Health Report', @enabled = 1, @description = 'Generate and send daily health report', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Generate Health Report', @step_name = 'Execute', @step_id = 1, @subsystem = 'TSQL', @command = 'EXEC DBAOps.usp_GenerateHealthReport;', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Generate Health Report', @name = 'DBAOps - Generate Health Report Schedule', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 1, @freq_subday_interval = 0, @active_start_time = 70000;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Generate Health Report', @server_name = '(local)';
GO

-- === DBAOps - Generate Schema Documentation ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Generate Schema Documentation')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Generate Schema Documentation', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Generate Schema Documentation', @enabled = 1, @description = 'Generates HTML schema documentation for all SQL Server databases across the enterprise. Replaces SchemaSpy with native PowerShell solution. Output: {{InstallPath}}\WebDashboard\SchemaDocs\', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Generate Schema Documentation', @step_name = 'Generate Schema Documentation', @step_id = 1, @subsystem = 'PowerShell', @command = '& "{{InstallPath}}\PowerShell\Generate-SchemaDocumentation.ps1"', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Generate Schema Documentation', @name = 'Weekly Sunday 3AM', @freq_type = 8, @freq_interval = 1, @freq_subday_type = 1, @freq_subday_interval = 0, @active_start_time = 30000;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Generate Schema Documentation', @server_name = '(local)';
GO

-- === DBAOps â€“ Hourly Compliance Collection & Report ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps â€“ Hourly Compliance Collection & Report')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps â€“ Hourly Compliance Collection & Report', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps â€“ Hourly Compliance Collection & Report', @enabled = 1, @description = 'Collects all compliance data and sends hourly CJIS/NIST/DISA report. Author: RHOYLLE INNOVATION EMPIRE LLC', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Hourly Compliance Collection & Report', @step_name = 'Collect All Data', @step_id = 1, @subsystem = 'TSQL', @command = 'EXEC DBAOpsRepository.ctl.usp_MasterDataCollection;', @on_success_action = 3, @on_fail_action = 3;
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Hourly Compliance Collection & Report', @step_name = 'Send Compliance Report', @step_id = 2, @subsystem = 'TSQL', @command = 'EXEC DBAOpsRepository.alert.usp_ComprehensiveComplianceReport @SendEmail = 1;', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps â€“ Hourly Compliance Collection & Report', @name = 'DBAOps_Hourly_ComplianceReport', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 8, @freq_subday_interval = 1, @active_start_time = 0;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps â€“ Hourly Compliance Collection & Report', @server_name = '(local)';
GO

-- === DBAOps - Hourly Environment Check (Alerts Only) ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Hourly Environment Check (Alerts Only)')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Hourly Environment Check (Alerts Only)', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Hourly Environment Check (Alerts Only)', @enabled = 1, @description = 'Runs hourly check and emails ONLY if critical or high issues are found.', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Hourly Environment Check (Alerts Only)', @step_name = 'Run Hourly Check - Alert on Issues Only', @step_id = 1, @subsystem = 'TSQL', @command = '
SET NOCOUNT ON;

DECLARE @CriticalCount INT = 0;
DECLARE @AlertHTML NVARCHAR(MAX) = '''';
DECLARE @Subject NVARCHAR(255);

-- =====================================================
-- Check for critical issues using CMS as source of truth
-- =====================================================

-- 1. Check for unreachable servers (last seen > 1 hour ago)
SELECT @CriticalCount = COUNT(*)
FROM msdb.dbo.sysmanagement_shared_registered_servers_internal cms
LEFT JOIN config.ServerInventory si ON cms.server_name = si.ServerName
WHERE cms.server_name NOT LIKE ''%\%'' 
  AND cms.server_name <> @@SERVERNAME
  AND (si.LastSeen IS NULL OR si.LastSeen < DATEADD(HOUR, -1, GETDATE()));

-- 2. Check for failed jobs in last hour
DECLARE @FailedJobs INT;
SELECT @FailedJobs = COUNT(DISTINCT j.name)
FROM msdb.dbo.sysjobs j
JOIN msdb.dbo.sysjobhistory h ON j.job_id = h.job_id
WHERE h.run_status = 0
  AND h.step_id = 0
  AND msdb.dbo.agent_datetime(h.run_date, h.run_time) > DATEADD(HOUR, -1, GETDATE())
  AND j.name LIKE ''DBAOps%'';

SET @CriticalCount = @CriticalCount + @FailedJobs;

-- 3. Check for blocking > 5 minutes
DECLARE @BlockingCount INT = 0;
SELECT @BlockingCount = COUNT(*)
FROM audit.BlockingEvents
WHERE CollectedAt > DATEADD(HOUR, -1, GETDATE())
  AND BlockedWaitTime > 300;

SET @CriticalCount = @CriticalCount + @BlockingCount;

-- Only send email if there are critical issues
IF @CriticalCount > 0
BEGIN
    SET @Subject = ''âš ï¸ DBAOps ALERT: '' + CAST(@CriticalCount AS VARCHAR(10)) + '' Critical Issue(s) Detected'';
    
    SET @AlertHTML = N''<html><body style="font-family: Segoe UI, Arial;">
    <h2 style="color: #dc3545;">âš ï¸ DBAOps Hourly Alert</h2>
    <p>The following issues were detected:</p>
    <ul>
    <li>Failed DBAOps Jobs (last hour): '' + CAST(@FailedJobs AS VARCHAR(10)) + ''</li>
    <li>Blocking Events > 5 min: '' + CAST(@BlockingCount AS VARCHAR(10)) + ''</li>
    </ul>
    <p style="color: #666; font-size: 12px;">Source: CMS (124 servers) | Generated: '' + CONVERT(VARCHAR(30), GETDATE(), 120) + ''</p>
    </body></html>'';
    
    EXEC msdb.dbo.sp_send_dbmail
        @profile_name = ''DBAOpsProfile'',
        @recipients = ''dbaops@yourdomain.com'',
        @subject = @Subject,
        @body = @AlertHTML,
        @body_format = ''HTML'';
    
    PRINT ''Alert sent: '' + CAST(@CriticalCount AS VARCHAR(10)) + '' issues found'';
END
ELSE
BEGIN
    PRINT ''No critical issues found. No email sent.'';
END
', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Hourly Environment Check (Alerts Only)', @name = 'Hourly Weekdays 6AM-10PM Every 2 hours Weekends', @freq_type = 8 8, @freq_interval = 62 65, @freq_subday_type = 8 8, @freq_subday_interval = 1 2, @active_start_time = 60000 80000;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Hourly Environment Check (Alerts Only)', @server_name = '(local)';
GO

-- === DBAOps - Hourly Security Report ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Hourly Security Report')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Hourly Security Report', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Hourly Security Report', @enabled = 1, @description = 'Hourly security and compliance monitoring report - CJIS, NIST, DISA', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Hourly Security Report', @step_name = 'Generate Hourly Report', @step_id = 1, @subsystem = 'TSQL', @command = 'EXEC DBAOpsRepository.report.usp_UnifiedSecurityComplianceReport @ReportType = ''HOURLY'', @SendEmail = 1;', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Hourly Security Report', @name = 'Hourly_SecurityReport', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 8, @freq_subday_interval = 1, @active_start_time = 0;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Hourly Security Report', @server_name = '(local)';
GO

-- === DBAOps - Index Analysis Collector ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Index Analysis Collector')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Index Analysis Collector', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Index Analysis Collector', @enabled = 1, @description = 'Collects index usage statistics and missing index recommendations. Part of DBAOps monitoring platform.', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Index Analysis Collector', @step_name = 'Collect Index Analysis', @step_id = 1, @subsystem = 'TSQL', @command = '
EXEC DBAOpsRepository.perf.usp_CollectIndexUsage;
EXEC DBAOpsRepository.perf.usp_CollectMissingIndexes;
PRINT ''Index analysis collected successfully'';', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Index Analysis Collector', @name = 'Daily at 2 AM', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 1, @freq_subday_interval = 0, @active_start_time = 20000;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Index Analysis Collector', @server_name = '(local)';
GO

-- === DBAOps - IndexOptimize Parameter Compliance ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - IndexOptimize Parameter Compliance')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - IndexOptimize Parameter Compliance', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - IndexOptimize Parameter Compliance', @enabled = 1, @description = 'Scans all CMS-registered servers for SQL Agent job parameter compliance issues. Uses CMS as source of truth. Auto-fixes issues and records results to DBAOpsRepository.', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - IndexOptimize Parameter Compliance', @step_name = 'Run Job Compliance Scan', @step_id = 1, @subsystem = 'CmdExec', @command = 'powershell.exe -ExecutionPolicy Bypass -NoProfile -Command "
    Import-Module ''{{InstallPath}}\PowerShell\DBAOps.JobCompliance.psm1'' -Force
    $Result = Invoke-DBAOpsJobComplianceScan -AutoFix $true -SendNotification $true
    if ($Result.Statistics.Failed -gt 0) { exit 1 }
    exit 0
"', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - IndexOptimize Parameter Compliance', @name = 'Weekly Sunday 5AM', @freq_type = 8, @freq_interval = 1, @freq_subday_type = 1, @freq_subday_interval = 0, @active_start_time = 50000;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - IndexOptimize Parameter Compliance', @server_name = '(local)';
GO

-- === DBAOps â€“ Infrastructure Inventory Collector ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps â€“ Infrastructure Inventory Collector')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps â€“ Infrastructure Inventory Collector', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps â€“ Infrastructure Inventory Collector', @enabled = 1, @description = 'Collects comprehensive infrastructure inventory: security, permissions, file growth, applications. Author: RHOYLLE INNOVATION EMPIRE LLC', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Infrastructure Inventory Collector', @step_name = 'Collect File Growth Config', @step_id = 1, @subsystem = 'TSQL', @command = 'EXEC inventory.usp_Collect_FileGrowthConfig_AllServers;', @on_success_action = 3, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Infrastructure Inventory Collector', @step_name = 'Collect Security Inventory', @step_id = 2, @subsystem = 'TSQL', @command = 'EXEC security.usp_Collect_SecurityInventory_AllServers;', @on_success_action = 3, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Infrastructure Inventory Collector', @step_name = 'Collect Application Mapping', @step_id = 3, @subsystem = 'TSQL', @command = 'EXEC inventory.usp_Collect_ApplicationMapping;', @on_success_action = 3, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Infrastructure Inventory Collector', @step_name = 'Collect Database Inventory All Servers', @step_id = 4, @subsystem = 'TSQL', @command = 'EXEC inventory.usp_Collect_DatabaseInventory_AllServers;', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps â€“ Infrastructure Inventory Collector', @name = 'Daily 6 AM', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 1, @freq_subday_interval = 0, @active_start_time = 60000;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps â€“ Infrastructure Inventory Collector', @server_name = '(local)';
GO

-- === DBAOps â€“ Job Integrity & Compliance Monitor ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps â€“ Job Integrity & Compliance Monitor')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps â€“ Job Integrity & Compliance Monitor', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps â€“ Job Integrity & Compliance Monitor', @enabled = 1, @description = 'Collects SQL Agent job health & compliance', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Job Integrity & Compliance Monitor', @step_name = 'Monitor Job Integrity', @step_id = 1, @subsystem = 'TSQL', @command = '
SET NOCOUNT ON;

BEGIN TRY
    -- Check for failed jobs in last 24 hours
    SELECT 
        j.name AS JobName,
        msdb.dbo.agent_datetime(jh.run_date, jh.run_time) AS FailureTime,
        LEFT(jh.message, 200) AS ErrorMessage
    FROM msdb.dbo.sysjobs j
    JOIN msdb.dbo.sysjobhistory jh ON j.job_id = jh.job_id
    WHERE jh.step_id = 0
    AND jh.run_status = 0
    AND msdb.dbo.agent_datetime(jh.run_date, jh.run_time) >= DATEADD(HOUR, -24, GETDATE())
    AND j.enabled = 1
    ORDER BY jh.run_date DESC, jh.run_time DESC;
    
    PRINT ''Job Integrity Check Complete - '' + CONVERT(VARCHAR, GETDATE(), 120);
END TRY
BEGIN CATCH
    PRINT ''Error: '' + ERROR_MESSAGE();
END CATCH
', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps â€“ Job Integrity & Compliance Monitor', @name = 'DBAOps â€“ Every 30 Minutes', @freq_type = 4, @freq_interval = 30, @freq_subday_type = 1, @freq_subday_interval = 0, @active_start_time = 0;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps â€“ Job Integrity & Compliance Monitor', @server_name = '(local)';
GO

-- === DBAOps â€“ JobIntegrity Unhealthy Alert ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps â€“ JobIntegrity Unhealthy Alert')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps â€“ JobIntegrity Unhealthy Alert', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps â€“ JobIntegrity Unhealthy Alert', @enabled = 1, @description = 'No description available.', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ JobIntegrity Unhealthy Alert', @step_name = 'Send Unhealthy Job Alerts', @step_id = 1, @subsystem = 'TSQL', @command = 'EXEC DBAOpsRepository.dbo.usp_JobIntegrity_UnhealthyAlert;', @on_success_action = 1, @on_fail_action = 4;
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ JobIntegrity Unhealthy Alert', @step_name = 'Send Failure Alert', @step_id = 2, @subsystem = 'TSQL', @command = '
EXEC msdb.dbo.sp_send_dbmail
    @profile_name = ''DBAOpsProfile'',
    @recipients   = ''dbaops@yourdomain.com'',
    @subject      = ''*** SQL ALERT: Job Failure â€“ $(ESCAPE_NONE(JOBNAME)) ***'',
    @body         = ''SQL Agent detected a failure in job "$(ESCAPE_NONE(JOBNAME))" on server "$(ESCAPE_NONE(SRVR))".'',
    @body_format  = ''TEXT'';
', @on_success_action = 1, @on_fail_action = 1;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps â€“ JobIntegrity Unhealthy Alert', @name = 'DBAOps â€“ Every 15 Minutes â€“ JobIntegrityAlert', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 4, @freq_subday_interval = 15, @active_start_time = 0;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps â€“ JobIntegrity Unhealthy Alert', @server_name = '(local)';
GO

-- === DBAOps â€“ Load Backup Compliance ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps â€“ Load Backup Compliance')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps â€“ Load Backup Compliance', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps â€“ Load Backup Compliance', @enabled = 1, @description = 'Loads Veeam backup compliance data into ctl.BackupCompliance.', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Load Backup Compliance', @step_name = 'Execute BackupCompliance ETL', @step_id = 1, @subsystem = 'TSQL', @command = 'EXEC ctl.usp_Load_BackupCompliance;', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Load Backup Compliance', @step_name = 'Load Data', @step_id = 2, @subsystem = 'TSQL', @command = 'EXEC ctl.usp_Load_BackupCompliance;', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps â€“ Load Backup Compliance', @name = 'Hourly Backup Compliance Loader', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 4, @freq_subday_interval = 60, @active_start_time = 500;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps â€“ Load Backup Compliance', @server_name = '(local)';
GO

-- === DBAOps - Load Repository Status ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Load Repository Status')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Load Repository Status', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Load Repository Status', @enabled = 1, @description = 'Collects disk space information from Veeam backup repositories on AZVEEAM25 and updates config.RepositoryAssignment table. Uses PowerShell script at {{InstallPath}}\Get-VeeamRepositoryDiskSpace.ps1. Runs every 4 hours.', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Load Repository Status', @step_name = 'Collect Veeam Repository Disk Space', @step_id = 1, @subsystem = 'CmdExec', @command = 'powershell.exe -ExecutionPolicy Bypass -File "{{InstallPath}}\Get-VeeamRepositoryDiskSpace.ps1"', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Load Repository Status', @name = 'Every 4 Hours - Repository Status', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 8, @freq_subday_interval = 4, @active_start_time = 0;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Load Repository Status', @server_name = '(local)';
GO

-- === DBAOps â€“ Local Admin Compliance Audit ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps â€“ Local Admin Compliance Audit')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps â€“ Local Admin Compliance Audit', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps â€“ Local Admin Compliance Audit', @enabled = 1, @description = 'Runs security.usp_CollectMissingLocalAdmins to evaluate missing local admin accounts.', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Local Admin Compliance Audit', @step_name = 'Audit Local Admin Compliance', @step_id = 1, @subsystem = 'TSQL', @command = '
SET NOCOUNT ON;

BEGIN TRY
    -- Check sysadmin role members
    SELECT 
        sp.name AS LoginName,
        sp.type_desc AS LoginType,
        sp.create_date AS CreatedDate,
        sp.modify_date AS ModifiedDate,
        sp.is_disabled AS IsDisabled
    FROM sys.server_principals sp
    JOIN sys.server_role_members srm ON sp.principal_id = srm.member_principal_id
    JOIN sys.server_principals sr ON srm.role_principal_id = sr.principal_id
    WHERE sr.name = ''sysadmin''
    ORDER BY sp.name;
    
    -- Update compliance table if exists
    IF OBJECT_ID(''security.MissingLocalAdminCompliance'', ''U'') IS NOT NULL
    BEGIN
        -- Update with current sysadmin count
        DECLARE @SysadminCount INT;
        SELECT @SysadminCount = COUNT(*) 
        FROM sys.server_principals sp
        JOIN sys.server_role_members srm ON sp.principal_id = srm.member_principal_id
        JOIN sys.server_principals sr ON srm.role_principal_id = sr.principal_id
        WHERE sr.name = ''sysadmin'';
        
        PRINT ''Sysadmin members: '' + CAST(@SysadminCount AS VARCHAR);
    END
    
    PRINT ''Local Admin Compliance Audit Complete - '' + CONVERT(VARCHAR, GETDATE(), 120);
END TRY
BEGIN CATCH
    PRINT ''Error: '' + ERROR_MESSAGE();
END CATCH
', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps â€“ Local Admin Compliance Audit', @name = 'Daily â€“ 6AM Local Admin Compliance Check', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 1, @freq_subday_interval = 0, @active_start_time = 60000;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps â€“ Local Admin Compliance Audit', @server_name = '(local)';
GO

-- === DBAOps - Log Retention Cleanup ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Log Retention Cleanup')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Log Retention Cleanup', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Log Retention Cleanup', @enabled = 1, @description = 'Cleanup log data', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Log Retention Cleanup', @step_name = 'Execute', @step_id = 1, @subsystem = 'TSQL', @command = 'EXEC DBAOpsRepository.DBAOps.usp_CleanupHistory @RetentionDays = 90;', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Log Retention Cleanup', @name = 'DBAOps - Log Retention Cleanup Schedule', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 1, @freq_subday_interval = 0, @active_start_time = 10000;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Log Retention Cleanup', @server_name = '(local)';
GO

-- === DBAOps â€“ Login Drift Monitor ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps â€“ Login Drift Monitor')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps â€“ Login Drift Monitor', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps â€“ Login Drift Monitor', @enabled = 1, @description = 'Compares current SQL logins against baseline in sec.SecurityBaseline.', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Login Drift Monitor', @step_name = 'Drift Check', @step_id = 1, @subsystem = 'PowerShell', @command = '& "{{InstallPath}}\PowerShell\Invoke-LoginDriftCheck.ps1"', @on_success_action = 1, @on_fail_action = 4;
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Login Drift Monitor', @step_name = 'Send Failure Alert', @step_id = 2, @subsystem = 'TSQL', @command = '
EXEC msdb.dbo.sp_send_dbmail
    @profile_name = ''DBAOpsProfile'',
    @recipients   = ''dbaops@yourdomain.com'',
    @subject      = ''*** SQL ALERT: Job Failure â€“ $(ESCAPE_NONE(JOBNAME)) ***'',
    @body         = ''SQL Agent detected a failure in job "$(ESCAPE_NONE(JOBNAME))" on server "$(ESCAPE_NONE(SRVR))".'',
    @body_format  = ''TEXT'';
', @on_success_action = 1, @on_fail_action = 1;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps â€“ Login Drift Monitor', @name = 'Every 1 Hour', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 8, @freq_subday_interval = 1, @active_start_time = 0;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps â€“ Login Drift Monitor', @server_name = '(local)';
GO

-- === DBAOps â€“ Maintenance â€“ msdb Job History Cleanup ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps â€“ Maintenance â€“ msdb Job History Cleanup')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps â€“ Maintenance â€“ msdb Job History Cleanup', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps â€“ Maintenance â€“ msdb Job History Cleanup', @enabled = 1, @description = 'DBAOps-governed msdb SQL Agent job history retention cleanup with HTML reporting.', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Maintenance â€“ msdb Job History Cleanup', @step_name = 'Execute Cleanup', @step_id = 1, @subsystem = 'TSQL', @command = 'EXEC dbo.usp_DBAOps_msdb_JobHistoryCleanup;', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps â€“ Maintenance â€“ msdb Job History Cleanup', @name = 'DBAOps â€“ Monthly â€“ First Sunday â€“ 1AM', @freq_type = 32, @freq_interval = 1, @freq_subday_type = 1, @freq_subday_interval = 0, @active_start_time = 10000;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps â€“ Maintenance â€“ msdb Job History Cleanup', @server_name = '(local)';
GO

-- === DBAOps â€“ MasterCollector ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps â€“ MasterCollector')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps â€“ MasterCollector', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps â€“ MasterCollector', @enabled = 1, @description = 'Centralized collector for Backup, Job, Login, and Service compliance across all configured SQL Servers.', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ MasterCollector', @step_name = 'Run DBAOps Master Collector', @step_id = 1, @subsystem = 'TSQL', @command = '
        USE DBAOpsRepository;
        EXEC fact.usp_Collect_DBAOpsMetrics;
    ', @on_success_action = 1, @on_fail_action = 4;
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ MasterCollector', @step_name = 'Send Failure Alert', @step_id = 2, @subsystem = 'TSQL', @command = '
EXEC msdb.dbo.sp_send_dbmail
    @profile_name = ''DBAOpsProfile'',
    @recipients   = ''dbaops@yourdomain.com'',
    @subject      = ''*** SQL ALERT: Job Failure â€“ $(ESCAPE_NONE(JOBNAME)) ***'',
    @body         = ''SQL Agent detected a failure in job "$(ESCAPE_NONE(JOBNAME))" on server "$(ESCAPE_NONE(SRVR))".'',
    @body_format  = ''TEXT'';
', @on_success_action = 1, @on_fail_action = 1;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps â€“ MasterCollector', @name = 'DBAOps â€“ Every 15 Minutes', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 4, @freq_subday_interval = 15, @active_start_time = 0;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps â€“ MasterCollector', @server_name = '(local)';
GO

-- === DBAOps â€“ Memory Compliance Collector ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps â€“ Memory Compliance Collector')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps â€“ Memory Compliance Collector', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps â€“ Memory Compliance Collector', @enabled = 1, @description = 'No description available.', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Memory Compliance Collector', @step_name = 'Collect Memory Compliance', @step_id = 1, @subsystem = 'TSQL', @command = 'EXEC DBAOpsRepository.ctl.usp_Collect_MemoryCompliance;', @on_success_action = 1, @on_fail_action = 4;
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Memory Compliance Collector', @step_name = 'Send Failure Alert', @step_id = 2, @subsystem = 'TSQL', @command = '
EXEC msdb.dbo.sp_send_dbmail
    @profile_name = ''DBAOpsProfile'',
    @recipients   = ''dbaops@yourdomain.com'',
    @subject      = ''*** SQL ALERT: Job Failure â€“ $(ESCAPE_NONE(JOBNAME)) ***'',
    @body         = ''SQL Agent detected a failure in job "$(ESCAPE_NONE(JOBNAME))" on server "$(ESCAPE_NONE(SRVR))".'',
    @body_format  = ''TEXT'';
', @on_success_action = 1, @on_fail_action = 1;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps â€“ Memory Compliance Collector', @name = 'DBAOps â€“ Memory Compliance Every 15 Minutes', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 4, @freq_subday_interval = 15, @active_start_time = 0;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps â€“ Memory Compliance Collector', @server_name = '(local)';
GO

-- === DBAOps - Monitor Replication ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Monitor Replication')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Monitor Replication', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Monitor Replication', @enabled = 1, @description = 'Monitor replication publication and subscription status', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Monitor Replication', @step_name = 'Execute', @step_id = 1, @subsystem = 'TSQL', @command = 'EXEC DBAOpsRepository.replmon.usp_MonitorReplication;', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Monitor Replication', @name = 'DBAOps - Monitor Replication Schedule', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 4, @freq_subday_interval = 5, @active_start_time = 0;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Monitor Replication', @server_name = '(local)';
GO

-- === DBAOps â€“ Parallelism Compliance Report ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps â€“ Parallelism Compliance Report')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps â€“ Parallelism Compliance Report', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps â€“ Parallelism Compliance Report', @enabled = 1, @description = 'Weekly parallelism and configuration compliance report per CJIS/NIST/DISA standards. Author: RHOYLLE INNOVATION EMPIRE LLC', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Parallelism Compliance Report', @step_name = 'Collect Server Configuration', @step_id = 1, @subsystem = 'TSQL', @command = 'EXEC DBAOpsRepository.dbo.usp_CollectServerConfigCompliance;', @on_success_action = 3, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Parallelism Compliance Report', @step_name = 'Send Compliance Report', @step_id = 2, @subsystem = 'TSQL', @command = 'EXEC DBAOpsRepository.alert.usp_ParallelismComplianceReport @SendEmail = 1;', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps â€“ Parallelism Compliance Report', @name = 'DBAOps_Weekly_Monday_7AM', @freq_type = 8, @freq_interval = 2, @freq_subday_type = 1, @freq_subday_interval = 0, @active_start_time = 70000;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps â€“ Parallelism Compliance Report', @server_name = '(local)';
GO

-- === DBAOps â€“ Performance Collector ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps â€“ Performance Collector')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps â€“ Performance Collector', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps â€“ Performance Collector', @enabled = 1, @description = 'Collects performance metrics (CPU, waits, IO).', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Performance Collector', @step_name = 'Collect Performance Metrics', @step_id = 1, @subsystem = 'TSQL', @command = 'USE DBAOpsRepository;
EXEC dbo.usp_Collect_PerformanceCompliance_Centralized;', @on_success_action = 1, @on_fail_action = 4;
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Performance Collector', @step_name = 'Send Failure Alert', @step_id = 2, @subsystem = 'TSQL', @command = '
EXEC msdb.dbo.sp_send_dbmail
    @profile_name = ''DBAOpsProfile'',
    @recipients   = ''dbaops@yourdomain.com'',
    @subject      = ''*** SQL ALERT: Job Failure â€“ $(ESCAPE_NONE(JOBNAME)) ***'',
    @body         = ''SQL Agent detected a failure in job "$(ESCAPE_NONE(JOBNAME))" on server "$(ESCAPE_NONE(SRVR))".'',
    @body_format  = ''TEXT'';
', @on_success_action = 1, @on_fail_action = 1;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps â€“ Performance Collector', @name = 'DBAOps â€“ Performance Every 15 Minutes', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 4, @freq_subday_interval = 15, @active_start_time = 0;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps â€“ Performance Collector', @server_name = '(local)';
GO

-- === DBAOps - Performance Telemetry Collector ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Performance Telemetry Collector')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Performance Telemetry Collector', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Performance Telemetry Collector', @enabled = 1, @description = 'No description available.', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Performance Telemetry Collector', @step_name = 'Collect Query Telemetry', @step_id = 1, @subsystem = 'TSQL', @command = '
INSERT INTO DBAOps.PerformanceTelemetry
(
    ServerName,
    DatabaseName,
    DatabaseID,
    QueryHash,
    ExecutionCount,
    TotalCPU,
    TotalDuration,
    TotalReads,
    CaptureTime
)
SELECT
    @@SERVERNAME AS ServerName,
    ISNULL(DB_NAME(st.dbid), ''UNKNOWN'') AS DatabaseName,
    st.dbid AS DatabaseID,
    qs.query_hash,
    qs.execution_count,
    qs.total_worker_time,
    qs.total_elapsed_time,
    qs.total_logical_reads,
    SYSUTCDATETIME() AS CaptureTime
FROM sys.dm_exec_query_stats qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) st;
', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Performance Telemetry Collector', @step_name = 'Collect Telemetry', @step_id = 2, @subsystem = 'TSQL', @command = '
INSERT INTO DBAOps.PerformanceTelemetry
(
    ServerName,
    DatabaseName,
    DatabaseID,
    QueryHash,
    ExecutionCount,
    TotalCPU,
    TotalDuration,
    TotalReads,
    CaptureTime
)
SELECT
    @@SERVERNAME AS ServerName,
    ISNULL(DB_NAME(st.dbid), ''UNKNOWN'') AS DatabaseName,
    st.dbid AS DatabaseID,
    qs.query_hash,
    qs.execution_count,
    qs.total_worker_time,
    qs.total_elapsed_time,
    qs.total_logical_reads,
    SYSUTCDATETIME() AS CaptureTime
FROM sys.dm_exec_query_stats qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) st;
', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Performance Telemetry Collector', @name = 'DBAOps - Performance Telemetry Schedule', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 4, @freq_subday_interval = 5, @active_start_time = 0;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Performance Telemetry Collector', @server_name = '(local)';
GO

-- === DBAOps â€“ Permission Drift Monitor ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps â€“ Permission Drift Monitor')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps â€“ Permission Drift Monitor', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps â€“ Permission Drift Monitor', @enabled = 1, @description = 'Monitors server/database-level permission changes.', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Permission Drift Monitor', @step_name = 'Permission Drift', @step_id = 1, @subsystem = 'PowerShell', @command = '& "{{InstallPath}}\PowerShell\Invoke-PermissionDriftCheck.ps1"', @on_success_action = 1, @on_fail_action = 4;
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Permission Drift Monitor', @step_name = 'Send Failure Alert', @step_id = 2, @subsystem = 'TSQL', @command = '
EXEC msdb.dbo.sp_send_dbmail
    @profile_name = ''DBAOpsProfile'',
    @recipients   = ''dbaops@yourdomain.com'',
    @subject      = ''*** SQL ALERT: Job Failure â€“ $(ESCAPE_NONE(JOBNAME)) ***'',
    @body         = ''SQL Agent detected a failure in job "$(ESCAPE_NONE(JOBNAME))" on server "$(ESCAPE_NONE(SRVR))".'',
    @body_format  = ''TEXT'';
', @on_success_action = 1, @on_fail_action = 1;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps â€“ Permission Drift Monitor', @name = 'Every 1 Hour', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 8, @freq_subday_interval = 1, @active_start_time = 0;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps â€“ Permission Drift Monitor', @server_name = '(local)';
GO

-- === DBAOps - Playbook Maintenance ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Playbook Maintenance')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Playbook Maintenance', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Playbook Maintenance', @enabled = 1, @description = 'Maintains playbook execution history, cleans up old records, updates statistics.', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Playbook Maintenance', @step_name = 'Cleanup Old Executions', @step_id = 1, @subsystem = 'TSQL', @command = '
SET QUOTED_IDENTIFIER ON;
SET ANSI_NULLS ON;

-- Archive executions older than 90 days
UPDATE playbook.ExecutionHistory
SET Status = CONCAT(Status, '' (Archived)'')
WHERE CompletedDate < DATEADD(DAY, -90, GETDATE())
  AND Status NOT LIKE ''%Archived%'';

PRINT CONCAT(''Archived executions: '', @@ROWCOUNT);

-- Clean up orphaned step executions
DELETE se FROM playbook.StepExecution se
WHERE NOT EXISTS (SELECT 1 FROM playbook.ExecutionHistory eh WHERE eh.ExecutionID = se.ExecutionID);

PRINT CONCAT(''Orphaned steps cleaned: '', @@ROWCOUNT);

-- Clean up old checkpoints
DELETE FROM playbook.Checkpoints
WHERE CreatedDate < DATEADD(DAY, -30, GETDATE())
  AND RestoredDate IS NULL;

PRINT CONCAT(''Old checkpoints cleaned: '', @@ROWCOUNT);
', @on_success_action = 3, @on_fail_action = 3;
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Playbook Maintenance', @step_name = 'Update Playbook Stats', @step_id = 2, @subsystem = 'TSQL', @command = '
-- Log daily playbook usage stats
SELECT 
    CAST(GETDATE() AS DATE) AS ReportDate,
    COUNT(*) AS TotalExecutions,
    SUM(CASE WHEN Status = ''Completed'' THEN 1 ELSE 0 END) AS Successful,
    SUM(CASE WHEN Status = ''Failed'' THEN 1 ELSE 0 END) AS Failed,
    AVG(DATEDIFF(MINUTE, StartedDate, CompletedDate)) AS AvgDurationMin
FROM playbook.ExecutionHistory
WHERE StartedDate >= DATEADD(DAY, -1, GETDATE());

PRINT ''Playbook stats updated'';', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Playbook Maintenance', @name = 'Daily0300_PlaybookMaint', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 1, @freq_subday_interval = 0, @active_start_time = 30000;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Playbook Maintenance', @server_name = '(local)';
GO

-- === DBAOps - Populate Database Status ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Populate Database Status')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Populate Database Status', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Populate Database Status', @enabled = 1, @description = 'Populates fact.DatabaseStatus table', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Populate Database Status', @step_name = 'Populate Database Status', @step_id = 1, @subsystem = 'PowerShell', @command = 'powershell.exe -NoProfile -ExecutionPolicy Bypass -File "{{InstallPath}}\Collect-DatabaseStatus.ps1"', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Populate Database Status', @step_name = 'Collect DB Status via PowerShell', @step_id = 2, @subsystem = 'CmdExec', @command = 'powershell.exe -NoProfile -ExecutionPolicy Bypass -File "{{InstallPath}}\Collect-DatabaseStatus.ps1"', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Populate Database Status', @name = 'DBAOps - Every 30 Minutes', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 4, @freq_subday_interval = 30, @active_start_time = 0;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Populate Database Status', @server_name = '(local)';
GO

-- === DBAOps - Power BI Data Refresh ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Power BI Data Refresh')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Power BI Data Refresh', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Power BI Data Refresh', @enabled = 1, @description = 'Refreshes date dimension and other Power BI supporting data', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Power BI Data Refresh', @step_name = 'Refresh Date Dimension', @step_id = 1, @subsystem = 'TSQL', @command = 'EXEC pbi.usp_RefreshDateDimension;', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Power BI Data Refresh', @name = 'Daily at 12:05 AM', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 1, @freq_subday_interval = 0, @active_start_time = 500;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Power BI Data Refresh', @server_name = '(local)';
GO

-- === DBAOps - Process Alerts ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Process Alerts')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Process Alerts', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Process Alerts', @enabled = 1, @description = 'Processes all DBAOps alert rules and sends notifications for backup failures, disk space issues, and job failures.', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Process Alerts', @step_name = 'Process All Alerts', @step_id = 1, @subsystem = 'TSQL', @command = 'EXEC DBAOpsRepository.Alerting.usp_ProcessAllAlerts;', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Process Alerts', @name = 'Every 15 Minutes', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 4, @freq_subday_interval = 15, @active_start_time = 0;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Process Alerts', @server_name = '(local)';
GO

-- === DBAOps - Process Patch Queue ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Process Patch Queue')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Process Patch Queue', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Process Patch Queue', @enabled = 1, @description = 'Checks for queued patches and executes them via PowerShell', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Process Patch Queue', @step_name = 'Execute Queued Patches', @step_id = 1, @subsystem = 'CmdExec', @command = 'powershell.exe -ExecutionPolicy Bypass -File "{{InstallPath}}\PowerShell\Process-PatchQueue.ps1"', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Process Patch Queue', @name = 'Every 5 minutes', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 4, @freq_subday_interval = 5, @active_start_time = 0;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Process Patch Queue', @server_name = '(local)';
GO

-- === DBAOps - Process Veeam Backups ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Process Veeam Backups')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Process Veeam Backups', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Process Veeam Backups', @enabled = 1, @description = 'Process Veeam backup data into telemetry tables', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Process Veeam Backups', @step_name = 'Execute', @step_id = 1, @subsystem = 'TSQL', @command = '
DECLARE @Retry INT = 0;
DECLARE @MaxRetries INT = 3;
DECLARE @Success BIT = 0;

WHILE @Retry < @MaxRetries AND @Success = 0
BEGIN
    BEGIN TRY
        EXEC DBAOpsRepository.etl.usp_ProcessVeeamBackups;
        SET @Success = 1;
        PRINT ''Veeam backup processing completed successfully'';
    END TRY
    BEGIN CATCH
        SET @Retry = @Retry + 1;
        IF @Retry < @MaxRetries
        BEGIN
            PRINT ''Deadlock detected, retry '' + CAST(@Retry AS VARCHAR) + '' of '' + CAST(@MaxRetries AS VARCHAR);
            WAITFOR DELAY ''00:00:05'';  -- Wait 5 seconds before retry
        END
        ELSE
        BEGIN
            THROW;  -- Re-throw after max retries
        END
    END CATCH
END
', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Process Veeam Backups', @name = 'DBAOps - Process Veeam Backups Schedule', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 4, @freq_subday_interval = 15, @active_start_time = 0;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Process Veeam Backups', @server_name = '(local)';
GO

-- === DBAOps - PS Backup Compliance ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - PS Backup Compliance')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - PS Backup Compliance', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - PS Backup Compliance', @enabled = 1, @description = 'PowerShell: Backup compliance check', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - PS Backup Compliance', @step_name = 'Execute PowerShell', @step_id = 1, @subsystem = 'CmdExec', @command = 'powershell.exe -ExecutionPolicy Bypass -NoProfile -Command "& { . ''{{InstallPath}}\Scripts\DBAOps_DataCollection.ps1''; Start-DBAOpsCollection -BackupOnly }"', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - PS Backup Compliance', @name = 'DBAOps - PS Backup Compliance Schedule', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 8, @freq_subday_interval = 2, @active_start_time = 0;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - PS Backup Compliance', @server_name = '(local)';
GO

-- === DBAOps - PS Full Collection ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - PS Full Collection')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - PS Full Collection', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - PS Full Collection', @enabled = 1, @description = 'PowerShell: Full data collection from all servers ({{InstallPath}}\Scripts)', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - PS Full Collection', @step_name = 'Execute PowerShell', @step_id = 1, @subsystem = 'CmdExec', @command = 'powershell.exe -ExecutionPolicy Bypass -NoProfile -Command "& { . ''{{InstallPath}}\Scripts\DBAOps_DataCollection.ps1''; Start-DBAOpsCollection -Full }"', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - PS Full Collection', @name = 'DBAOps - PS Full Collection Schedule', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 1, @freq_subday_interval = 0, @active_start_time = 60000;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - PS Full Collection', @server_name = '(local)';
GO

-- === DBAOps - PS Inventory Collection ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - PS Inventory Collection')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - PS Inventory Collection', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - PS Inventory Collection', @enabled = 1, @description = 'PowerShell: Server and database inventory collection', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - PS Inventory Collection', @step_name = 'Execute PowerShell', @step_id = 1, @subsystem = 'CmdExec', @command = 'powershell.exe -ExecutionPolicy Bypass -NoProfile -Command "& { . ''{{InstallPath}}\Scripts\DBAOps_DataCollection.ps1''; Start-DBAOpsCollection -InventoryOnly }"', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - PS Inventory Collection', @name = 'DBAOps - PS Inventory Collection Schedule', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 8, @freq_subday_interval = 4, @active_start_time = 0;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - PS Inventory Collection', @server_name = '(local)';
GO

-- === DBAOps - PS Security Collection ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - PS Security Collection')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - PS Security Collection', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - PS Security Collection', @enabled = 1, @description = 'PowerShell: Permission and security data collection', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - PS Security Collection', @step_name = 'Execute PowerShell', @step_id = 1, @subsystem = 'CmdExec', @command = 'powershell.exe -ExecutionPolicy Bypass -NoProfile -Command "& { . ''{{InstallPath}}\Scripts\DBAOps_DataCollection.ps1''; Start-DBAOpsCollection -SecurityOnly }"', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - PS Security Collection', @name = 'DBAOps - PS Security Collection Schedule', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 1, @freq_subday_interval = 0, @active_start_time = 50000;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - PS Security Collection', @server_name = '(local)';
GO

-- === DBAOps - PS Self Heal ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - PS Self Heal')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - PS Self Heal', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - PS Self Heal', @enabled = 1, @description = 'PowerShell: Self-healing and cleanup', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - PS Self Heal', @step_name = 'Execute PowerShell', @step_id = 1, @subsystem = 'CmdExec', @command = 'powershell.exe -ExecutionPolicy Bypass -NoProfile -Command "& { . ''{{InstallPath}}\Scripts\DBAOps_DataCollection.ps1''; Start-DBAOpsCollection -SelfHealOnly }"', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - PS Self Heal', @name = 'DBAOps - PS Self Heal Schedule', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 8, @freq_subday_interval = 1, @active_start_time = 0;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - PS Self Heal', @server_name = '(local)';
GO

-- === DBAOps - Quarterly Threshold Review Reminder ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Quarterly Threshold Review Reminder')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Quarterly Threshold Review Reminder', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Quarterly Threshold Review Reminder', @enabled = 1, @description = 'NIST 800-53 Compliance: Sends reminder to review monitoring thresholds quarterly', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Quarterly Threshold Review Reminder', @step_name = 'Log Review Reminder', @step_id = 1, @subsystem = 'TSQL', @command = '
INSERT INTO log.AutomationLog (ModuleName, RunStatus, Message, LogType, LogMessage, LogTime)
VALUES (
    ''QuarterlyThresholdReview'', 
    ''Success'', 
    ''Quarterly threshold review reminder triggered - NIST 800-53 SI-4 compliance'',
    ''REMINDER'',
    ''Review config.MonitoringThresholds and config.DiskSpaceThresholds'',
    GETDATE()
);

PRINT ''=============================================''
PRINT ''QUARTERLY THRESHOLD REVIEW REMINDER''
PRINT ''NIST 800-53 SI-4 Compliance Requirement''
PRINT ''=============================================''
PRINT ''Review the following tables:''
PRINT ''  - config.MonitoringThresholds''
PRINT ''  - config.DiskSpaceThresholds''
PRINT ''=============================================''
', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Quarterly Threshold Review Reminder', @name = 'Quarterly - First Day of Quarter 8AM', @freq_type = 8, @freq_interval = 2, @freq_subday_type = 1, @freq_subday_interval = 0, @active_start_time = 80000;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Quarterly Threshold Review Reminder', @server_name = '(local)';
GO

-- === DBAOps - Reachability Check ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Reachability Check')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Reachability Check', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Reachability Check', @enabled = 1, @description = 'Runs PowerShell script to check reachability of 109 SQL Servers', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Reachability Check', @step_name = 'Run Reachability Script', @step_id = 1, @subsystem = 'PowerShell', @command = 'powershell.exe -ExecutionPolicy Bypass -File "{{InstallPath}}\Scripts\Check-Reachability.ps1"', @on_success_action = 1, @on_fail_action = 4;
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Reachability Check', @step_name = 'Send Failure Alert', @step_id = 2, @subsystem = 'TSQL', @command = '
EXEC msdb.dbo.sp_send_dbmail
    @profile_name = ''DBAOpsProfile'',
    @recipients   = ''dbaops@yourdomain.com'',
    @subject      = ''*** SQL ALERT: Job Failure â€“ $(ESCAPE_NONE(JOBNAME)) ***'',
    @body         = ''SQL Agent detected a failure in job "$(ESCAPE_NONE(JOBNAME))" on server "$(ESCAPE_NONE(SRVR))".'',
    @body_format  = ''TEXT'';
', @on_success_action = 1, @on_fail_action = 1;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Reachability Check', @name = 'Every 10 Minutes', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 4, @freq_subday_interval = 10, @active_start_time = 0;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Reachability Check', @server_name = '(local)';
GO

-- === DBAOps - Reachability Email Alerts ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Reachability Email Alerts')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Reachability Email Alerts', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Reachability Email Alerts', @enabled = 1, @description = 'Sends email alerts when a SQL Server goes offline', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Reachability Email Alerts', @step_name = 'Send Alerts', @step_id = 1, @subsystem = 'TSQL', @command = 'EXEC DBAOpsRepository.config.usp_SendReachabilityAlerts;', @on_success_action = 1, @on_fail_action = 4;
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Reachability Email Alerts', @step_name = 'Send Failure Alert', @step_id = 2, @subsystem = 'TSQL', @command = '
EXEC msdb.dbo.sp_send_dbmail
    @profile_name = ''DBAOpsProfile'',
    @recipients   = ''dbaops@yourdomain.com'',
    @subject      = ''*** SQL ALERT: Job Failure â€“ $(ESCAPE_NONE(JOBNAME)) ***'',
    @body         = ''SQL Agent detected a failure in job "$(ESCAPE_NONE(JOBNAME))" on server "$(ESCAPE_NONE(SRVR))".'',
    @body_format  = ''TEXT'';
', @on_success_action = 1, @on_fail_action = 1;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Reachability Email Alerts', @name = 'DBAOps Reachability Every 5 Minutes', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 4, @freq_subday_interval = 5, @active_start_time = 0;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Reachability Email Alerts', @server_name = '(local)';
GO

-- === DBAOps â€“ Refresh Calendar Dimension ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps â€“ Refresh Calendar Dimension')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps â€“ Refresh Calendar Dimension', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps â€“ Refresh Calendar Dimension', @enabled = 1, @description = 'No description available.', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Refresh Calendar Dimension', @step_name = 'Rebuild dim.Calendar', @step_id = 1, @subsystem = 'TSQL', @command = 'EXEC DBAOpsRepository.dbo.usp_RebuildCalendar;', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps â€“ Refresh Calendar Dimension', @name = 'Yearly Calendar Rebuild', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 1, @freq_subday_interval = 0, @active_start_time = 0;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps â€“ Refresh Calendar Dimension', @server_name = '(local)';
GO

-- === DBAOps - Refresh Dashboard Data ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Refresh Dashboard Data')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Refresh Dashboard Data', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Refresh Dashboard Data', @enabled = 1, @description = 'Updates dashboard data.json every 5 minutes. Includes tier deployment metrics.', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Refresh Dashboard Data', @step_name = 'Run PowerShell Script', @step_id = 1, @subsystem = 'PowerShell', @command = 'Set-Location {{InstallPath}}\PowerShell; .\Get-DBAOpsDashboardData.ps1', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Refresh Dashboard Data', @name = 'DBAOps Dashboard Every 5 Minutes', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 4, @freq_subday_interval = 5, @active_start_time = 0;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Refresh Dashboard Data', @server_name = '(local)';
GO

-- === DBAOps - Refresh Dashboard Metrics ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Refresh Dashboard Metrics')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Refresh Dashboard Metrics', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Refresh Dashboard Metrics', @enabled = 1, @description = 'Refresh pre-aggregated dashboard data', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Refresh Dashboard Metrics', @step_name = 'Execute', @step_id = 1, @subsystem = 'TSQL', @command = 'EXEC DBAOpsRepository.etl.usp_RefreshDashboardMetrics;', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Refresh Dashboard Metrics', @name = 'DBAOps - Refresh Dashboard Metrics Schedule', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 4, @freq_subday_interval = 5, @active_start_time = 0;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Refresh Dashboard Metrics', @server_name = '(local)';
GO

-- === DBAOps - Refresh Server Inventory ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Refresh Server Inventory')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Refresh Server Inventory', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Refresh Server Inventory', @enabled = 1, @description = 'Keeps config.ServerInventory current', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Refresh Server Inventory', @step_name = 'Refresh Server Inventory', @step_id = 1, @subsystem = 'TSQL', @command = 'EXEC DBAOpsRepository.config.usp_RefreshServerInventory;', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Refresh Server Inventory', @name = 'Every 4 hours - Server Inventory', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 8, @freq_subday_interval = 4, @active_start_time = 0;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Refresh Server Inventory', @server_name = '(local)';
GO

-- === DBAOps - Replication Health Monitor ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Replication Health Monitor')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Replication Health Monitor', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Replication Health Monitor', @enabled = 1, @description = 'DBAOps Enterprise™ Framework: Monitors replication health across all publishers. Thresholds: Latency 600s, Pending Cmds 10000. Runs every 15 minutes.', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Replication Health Monitor', @step_name = 'Collect Replication Health', @step_id = 1, @subsystem = 'TSQL', @command = 'EXEC ctl.usp_Check_ReplicationHealth @Verbose = 0, @LatencyThreshold = 600, @PendingCmdsThreshold = 600;', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Replication Health Monitor', @name = 'Every 15 Minutes', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 4, @freq_subday_interval = 15, @active_start_time = 0;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Replication Health Monitor', @server_name = '(local)';
GO

-- === DBAOps â€“ Schedule AutoFix ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps â€“ Schedule AutoFix')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps â€“ Schedule AutoFix', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps â€“ Schedule AutoFix', @enabled = 1, @description = 'Automatically heal schedule drift, fix disabled or missing schedules for DBAOps monitored jobs', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Schedule AutoFix', @step_name = 'Run Auto-Heal Engine', @step_id = 1, @subsystem = 'TSQL', @command = 'EXEC msdb.dbo.usp_DBAOps_AutoHealJobs;', @on_success_action = 1, @on_fail_action = 4;
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Schedule AutoFix', @step_name = 'Send Failure Alert', @step_id = 2, @subsystem = 'TSQL', @command = '
EXEC msdb.dbo.sp_send_dbmail
    @profile_name = ''DBAOpsProfile'',
    @recipients   = ''dbaops@yourdomain.com'',
    @subject      = ''*** SQL ALERT: Job Failure â€“ $(ESCAPE_NONE(JOBNAME)) ***'',
    @body         = ''SQL Agent detected a failure in job "$(ESCAPE_NONE(JOBNAME))" on server "$(ESCAPE_NONE(SRVR))".'',
    @body_format  = ''TEXT'';
', @on_success_action = 1, @on_fail_action = 1;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps â€“ Schedule AutoFix', @name = 'DBAOps â€“ Every 1 Hour', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 8, @freq_subday_interval = 1, @active_start_time = 0;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps â€“ Schedule AutoFix', @server_name = '(local)';
GO

-- === DBAOps - Security Audit Collector ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Security Audit Collector')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Security Audit Collector', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Security Audit Collector', @enabled = 1, @description = 'Collects security metrics: sysadmin membership, TDE status, orphaned users. Part of DBAOps monitoring platform.', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Security Audit Collector', @step_name = 'Collect Security Metrics', @step_id = 1, @subsystem = 'TSQL', @command = '
EXEC DBAOpsRepository.security.usp_CollectSysadminMembership;
EXEC DBAOpsRepository.security.usp_CollectTDEStatus;
EXEC DBAOpsRepository.security.usp_DetectOrphanedUsers;
PRINT ''Security audit collected successfully'';', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Security Audit Collector', @name = 'Every Hour', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 8, @freq_subday_interval = 1, @active_start_time = 0;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Security Audit Collector', @server_name = '(local)';
GO

-- === DBAOps â€“ Security Audit Monitor ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps â€“ Security Audit Monitor')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps â€“ Security Audit Monitor', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps â€“ Security Audit Monitor', @enabled = 1, @description = 'Monitors security changes and sends daily audit report. Author: RHOYLLE INNOVATION EMPIRE LLC', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Security Audit Monitor', @step_name = 'Collect Security Inventory', @step_id = 1, @subsystem = 'TSQL', @command = 'EXEC security.usp_Collect_SecurityInventory_AllServers;', @on_success_action = 3, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Security Audit Monitor', @step_name = 'Send Security Audit Report', @step_id = 2, @subsystem = 'TSQL', @command = 'EXEC alert.usp_SecurityAuditAlert @ThresholdHours = 24, @AlertThreshold = 100;', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps â€“ Security Audit Monitor', @name = 'Daily at 6 AM', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 1, @freq_subday_interval = 0, @active_start_time = 60000;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps â€“ Security Audit Monitor', @server_name = '(local)';
GO

-- === DBAOps â€“ Security Baseline Refresh ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps â€“ Security Baseline Refresh')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps â€“ Security Baseline Refresh', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps â€“ Security Baseline Refresh', @enabled = 1, @description = 'Rebuilds baseline: logins, permissions, role membership.', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Security Baseline Refresh', @step_name = 'Refresh Baseline', @step_id = 1, @subsystem = 'TSQL', @command = 'EXEC security.usp_RefreshSecurityBaseline;', @on_success_action = 1, @on_fail_action = 4;
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Security Baseline Refresh', @step_name = 'Send Failure Alert', @step_id = 2, @subsystem = 'TSQL', @command = '
EXEC msdb.dbo.sp_send_dbmail
    @profile_name = ''DBAOpsProfile'',
    @recipients   = ''dbaops@yourdomain.com'',
    @subject      = ''*** SQL ALERT: Job Failure â€“ $(ESCAPE_NONE(JOBNAME)) ***'',
    @body         = ''SQL Agent detected a failure in job "$(ESCAPE_NONE(JOBNAME))" on server "$(ESCAPE_NONE(SRVR))".'',
    @body_format  = ''TEXT'';
', @on_success_action = 1, @on_fail_action = 1;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps â€“ Security Baseline Refresh', @name = 'Daily 1 AM', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 1, @freq_subday_interval = 0, @active_start_time = 10000;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps â€“ Security Baseline Refresh', @server_name = '(local)';
GO

-- === DBAOps - Self Heal ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Self Heal')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Self Heal', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Self Heal', @enabled = 1, @description = 'Automated remediation of common issues', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Self Heal', @step_name = 'Execute', @step_id = 1, @subsystem = 'TSQL', @command = 'EXEC DBAOpsRepository.DBAOps.usp_SelfHeal;', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Self Heal', @name = 'DBAOps - Self Heal Schedule', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 4, @freq_subday_interval = 30, @active_start_time = 0;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Self Heal', @server_name = '(local)';
GO

-- === DBAOps - Self Heal TSQL ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Self Heal TSQL')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Self Heal TSQL', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Self Heal TSQL', @enabled = 1, @description = 'Automated remediation of common issues (T-SQL)', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Self Heal TSQL', @step_name = 'Execute', @step_id = 1, @subsystem = 'TSQL', @command = 'EXEC DBAOpsRepository.DBAOps.usp_SelfHeal;', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Self Heal TSQL', @name = 'DBAOps - Self Heal TSQL Schedule', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 4, @freq_subday_interval = 30, @active_start_time = 0;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Self Heal TSQL', @server_name = '(local)';
GO

-- === DBAOps â€“ Send Alert Emails ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps â€“ Send Alert Emails')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps â€“ Send Alert Emails', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps â€“ Send Alert Emails', @enabled = 1, @description = 'Sends email notifications for unprocessed alerts stored in fact_Alerts.', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Send Alert Emails', @step_name = 'Send Alert Emails', @step_id = 1, @subsystem = 'TSQL', @command = '
EXEC DBAOpsRepository.dbo.usp_SendAlertEmails;
', @on_success_action = 1, @on_fail_action = 4;
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Send Alert Emails', @step_name = 'Send Failure Alert', @step_id = 2, @subsystem = 'TSQL', @command = '
EXEC msdb.dbo.sp_send_dbmail
    @profile_name = ''DBAOpsProfile'',
    @recipients   = ''dbaops@yourdomain.com'',
    @subject      = ''*** SQL ALERT: Job Failure â€“ $(ESCAPE_NONE(JOBNAME)) ***'',
    @body         = ''SQL Agent detected a failure in job "$(ESCAPE_NONE(JOBNAME))" on server "$(ESCAPE_NONE(SRVR))".'',
    @body_format  = ''TEXT'';
', @on_success_action = 1, @on_fail_action = 1;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps â€“ Send Alert Emails', @name = 'DBAOps_SendEmails_Every1Min', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 4, @freq_subday_interval = 1, @active_start_time = 0;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps â€“ Send Alert Emails', @server_name = '(local)';
GO

-- === DBAOps â€“ Send Drift Alerts ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps â€“ Send Drift Alerts')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps â€“ Send Drift Alerts', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps â€“ Send Drift Alerts', @enabled = 1, @description = 'Sends consolidated DBAOps drift alert email for all pending drift detections.', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Send Drift Alerts', @step_name = 'Execute usp_DBAOps_SendDriftAlert', @step_id = 1, @subsystem = 'TSQL', @command = 'EXEC msdb.dbo.usp_DBAOps_SendDriftAlert;', @on_success_action = 1, @on_fail_action = 4;
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Send Drift Alerts', @step_name = 'Send Failure Alert', @step_id = 2, @subsystem = 'TSQL', @command = '
EXEC msdb.dbo.sp_send_dbmail
    @profile_name = ''DBAOpsProfile'',
    @recipients   = ''dbaops@yourdomain.com'',
    @subject      = ''*** SQL ALERT: Job Failure â€“ $(ESCAPE_NONE(JOBNAME)) ***'',
    @body         = ''SQL Agent detected a failure in job "$(ESCAPE_NONE(JOBNAME))" on server "$(ESCAPE_NONE(SRVR))".'',
    @body_format  = ''TEXT'';
', @on_success_action = 1, @on_fail_action = 1;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps â€“ Send Drift Alerts', @name = 'DBAOps â€“ Drift Alert Check (Every 5 Minutes)', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 4, @freq_subday_interval = 5, @active_start_time = 0;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps â€“ Send Drift Alerts', @server_name = '(local)';
GO

-- === DBAOps â€“ Send Teams Health Alerts ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps â€“ Send Teams Health Alerts')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps â€“ Send Teams Health Alerts', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps â€“ Send Teams Health Alerts', @enabled = 1, @description = 'Sends Adaptive Card SQL Server Health Alerts to Microsoft Teams.', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Send Teams Health Alerts', @step_name = 'Send Teams Adaptive Card', @step_id = 1, @subsystem = 'PowerShell', @command = '
$payload = Invoke-Sqlcmd -ServerInstance $env:COMPUTERNAME -Database "DBAOpsRepository" -Query "EXEC dbo.usp_GetTeamsHealthAdaptiveCard;" | Select-Object -ExpandProperty AdaptiveCardPayload

$uri = "https://yourdomain.com/dbaops/teamswebhook"  # Configure Teams webhook URL in DBAOps.config.json

try {
    Invoke-WebRequest -Uri $uri -Method POST -ContentType "application/json" -Body $payload
}
catch {
    $err = $_.Exception.Message
    Invoke-Sqlcmd -ServerInstance $env:COMPUTERNAME -Database "DBAOpsRepository" -Query "
        INSERT INTO dbo.FACT_ErrorLog(LogLevel, Category, MessageText, LogTime)
        VALUES(''ERROR'',''TeamsAlert'', ''$err'', GETDATE());
    "
}
', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps â€“ Send Teams Health Alerts', @name = 'DBAOps Teams Alerts â€“ Every 15 Minutes', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 4, @freq_subday_interval = 15, @active_start_time = 0;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps â€“ Send Teams Health Alerts', @server_name = '(local)';
GO

-- === DBAOps â€“ Server Health Collector ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps â€“ Server Health Collector')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps â€“ Server Health Collector', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps â€“ Server Health Collector', @enabled = 1, @description = 'Collects daily server health metrics', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Server Health Collector', @step_name = 'Collect Server Health', @step_id = 1, @subsystem = 'TSQL', @command = 'EXEC DBAOpsRepository.ctl.usp_Collect_ServerHealth;', @on_success_action = 1, @on_fail_action = 4;
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Server Health Collector', @step_name = 'Send Failure Alert', @step_id = 2, @subsystem = 'TSQL', @command = '
EXEC msdb.dbo.sp_send_dbmail
    @profile_name = ''DBAOpsProfile'',
    @recipients   = ''dbaops@yourdomain.com'',
    @subject      = ''*** SQL ALERT: Job Failure â€“ $(ESCAPE_NONE(JOBNAME)) ***'',
    @body         = ''SQL Agent detected a failure in job "$(ESCAPE_NONE(JOBNAME))" on server "$(ESCAPE_NONE(SRVR))".'',
    @body_format  = ''TEXT'';
', @on_success_action = 1, @on_fail_action = 1;
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Server Health Collector', @step_name = 'Run PowerShell Collector', @step_id = 3, @subsystem = 'PowerShell', @command = 'powershell.exe -NoProfile -File "{{InstallPath}}\Scripts\Deploy-DBAOpsServerHealthMonitoring.ps1"', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps â€“ Server Health Collector', @name = 'DBAOps â€“ Every 15 Minutes', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 4, @freq_subday_interval = 15, @active_start_time = 0;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps â€“ Server Health Collector', @server_name = '(local)';
GO

-- === DBAOps â€“ Server Reachability Monitor (PowerShell) ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps â€“ Server Reachability Monitor (PowerShell)')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps â€“ Server Reachability Monitor (PowerShell)', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps â€“ Server Reachability Monitor (PowerShell)', @enabled = 1, @description = 'PowerShell-based server reachability monitoring. Bypasses linked server encryption issues. Runs every 15 minutes. Author: RHOYLLE INNOVATION EMPIRE LLC', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Server Reachability Monitor (PowerShell)', @step_name = 'Run PowerShell Reachability Check', @step_id = 1, @subsystem = 'PowerShell', @command = '
# Define script path
$ScriptPath = "{{InstallPath}}\Server Reachability\ServerReachabilityMonitor.ps1"

# Verify script exists
if (!(Test-Path $ScriptPath)) {
    Write-Host "ERROR: Script not found at $ScriptPath"
    exit 1
}

# Run the monitoring script
& $ScriptPath -AlertThreshold 5 -MonitoringServer $env:COMPUTERNAME -DBAOpsDatabase "DBAOpsRepository" -EmailRecipient "dbaops@yourdomain.com"

# Exit with proper code
if ($?) { exit 0 } else { exit 1 }
', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps â€“ Server Reachability Monitor (PowerShell)', @name = 'Every 15 Minutes - Reachability Check', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 4, @freq_subday_interval = 15, @active_start_time = 0;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps â€“ Server Reachability Monitor (PowerShell)', @server_name = '(local)';
GO

-- === DBAOps â€“ Severe Compliance Alert ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps â€“ Severe Compliance Alert')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps â€“ Severe Compliance Alert', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps â€“ Severe Compliance Alert', @enabled = 1, @description = 'Checks for severe compliance issues every 5 min. Author: RHOYLLE INNOVATION EMPIRE LLC', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Severe Compliance Alert', @step_name = 'Check Severe Issues', @step_id = 1, @subsystem = 'TSQL', @command = '
DECLARE @SevereCount INT;
SELECT @SevereCount = COUNT(*)
FROM (
    SELECT h.ServerName
    FROM (
        SELECT *, ROW_NUMBER() OVER (PARTITION BY ServerName ORDER BY CaptureTime DESC) AS rn
        FROM DBAOpsRepository.metrics.FACT_ServerHealth 
        WHERE CaptureTime >= DATEADD(HOUR, -1, GETDATE())
    ) h
    LEFT JOIN (
        SELECT ServerName, MAX(100 - FreePercent) AS DiskUsed
        FROM DBAOpsRepository.fact.DiskSpaceMetrics 
        WHERE CaptureDate >= DATEADD(DAY, -1, GETDATE())
        GROUP BY ServerName
    ) d ON h.ServerName = d.ServerName
    WHERE h.rn = 1 AND (
        h.CPU_Utilization > 90 OR
        (h.Memory_UsedMB * 100.0 / NULLIF(h.Memory_TotalMB, 1)) > 90 OR
        h.Memory_PLE < 300 OR
        h.BlockingSessions > 5 OR
        ISNULL(d.DiskUsed, 0) > 85
    )
) x;

IF @SevereCount > 0
BEGIN
    -- Check cooldown (don''t spam - only alert if not sent in last 30 min)
    IF NOT EXISTS (
        SELECT 1 FROM msdb.dbo.sysmail_allitems 
        WHERE subject LIKE ''%SEVERE COMPLIANCE%'' 
          AND sent_date >= DATEADD(MINUTE, -30, GETDATE())
    )
    BEGIN
        EXEC DBAOpsRepository.alert.usp_ComprehensiveComplianceReport @SendEmail = 1;
    END
END
ELSE
    PRINT ''No severe issues found'';
', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps â€“ Severe Compliance Alert', @name = 'DBAOps_Every5Min_SevereAlert', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 4, @freq_subday_interval = 5, @active_start_time = 0;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps â€“ Severe Compliance Alert', @server_name = '(local)';
GO

-- === DBAOps â€“ SQL Connectivity Check ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps â€“ SQL Connectivity Check')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps â€“ SQL Connectivity Check', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps â€“ SQL Connectivity Check', @enabled = 1, @description = 'DBAOps Automated Job', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ SQL Connectivity Check', @step_name = 'Execute', @step_id = 1, @subsystem = 'PowerShell', @command = 'PowerShell.exe -NoProfile -ExecutionPolicy Bypass -Command "Import-Module ''{{InstallPath}}\Modules\DBAOps\DBAOps.psm1''; Test-NetConnection -ComputerName $ServerName -Port 1433"', @on_success_action = 1, @on_fail_action = 4;
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ SQL Connectivity Check', @step_name = 'Send Failure Alert', @step_id = 2, @subsystem = 'TSQL', @command = '
EXEC msdb.dbo.sp_send_dbmail
    @profile_name = ''DBAOpsProfile'',
    @recipients   = ''dbaops@yourdomain.com'',
    @subject      = ''*** SQL ALERT: Job Failure â€“ $(ESCAPE_NONE(JOBNAME)) ***'',
    @body         = ''SQL Agent detected a failure in job "$(ESCAPE_NONE(JOBNAME))" on server "$(ESCAPE_NONE(SRVR))".'',
    @body_format  = ''TEXT'';
', @on_success_action = 1, @on_fail_action = 1;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps â€“ SQL Connectivity Check', @name = 'Every 10 Minutes', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 4, @freq_subday_interval = 10, @active_start_time = 0;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps â€“ SQL Connectivity Check', @server_name = '(local)';
GO

-- === DBAOps â€“ SQL Error Log Collector ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps â€“ SQL Error Log Collector')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps â€“ SQL Error Log Collector', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps â€“ SQL Error Log Collector', @enabled = 1, @description = 'Collects SQL Server error logs from all servers.', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ SQL Error Log Collector', @step_name = 'Collect Error Logs', @step_id = 1, @subsystem = 'PowerShell', @command = '& "{{InstallPath}}\PowerShell\Collect-SQLErrorLogs.ps1"', @on_success_action = 1, @on_fail_action = 4;
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ SQL Error Log Collector', @step_name = 'Send Failure Alert', @step_id = 2, @subsystem = 'TSQL', @command = '
EXEC msdb.dbo.sp_send_dbmail
    @profile_name = ''DBAOpsProfile'',
    @recipients   = ''dbaops@yourdomain.com'',
    @subject      = ''*** SQL ALERT: Job Failure â€“ $(ESCAPE_NONE(JOBNAME)) ***'',
    @body         = ''SQL Agent detected a failure in job "$(ESCAPE_NONE(JOBNAME))" on server "$(ESCAPE_NONE(SRVR))".'',
    @body_format  = ''TEXT'';
', @on_success_action = 1, @on_fail_action = 1;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps â€“ SQL Error Log Collector', @name = 'Every 30 Minutes', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 4, @freq_subday_interval = 30, @active_start_time = 0;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps â€“ SQL Error Log Collector', @server_name = '(local)';
GO

-- === DBAOps - Sync ServerComplianceRules ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Sync ServerComplianceRules')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Sync ServerComplianceRules', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Sync ServerComplianceRules', @enabled = 1, @description = 'Automatically synchronizes ServerComplianceRules with linked servers. Adds missing servers with default compliance settings (RPO=24hrs, Full+Log, High criticality). Runs daily at 6:00 AM before compliance reports.', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Sync ServerComplianceRules', @step_name = 'Sync ServerComplianceRules with Linked Servers', @step_id = 1, @subsystem = 'TSQL', @command = '
/*
================================================================================
Auto-Sync ServerComplianceRules with Linked Servers
================================================================================
*/
SET NOCOUNT ON;

DECLARE @InsertedCount INT = 0;
DECLARE @Message NVARCHAR(500);

-- Insert missing linked servers into ServerComplianceRules
INSERT INTO [DBAOpsRepository].[config].[ServerComplianceRules] 
    (ServerName, RPOHours, BackupMode, Criticality, GraceHours, IsActive, CreatedOn)
SELECT 
    s.name AS ServerName,
    24 AS RPOHours,           -- Default: 24 hour RPO
    ''Full+Log'' AS BackupMode,  -- Default: Full + Log backups
    ''High'' AS Criticality,     -- Default: High criticality
    0 AS GraceHours,          -- Default: No grace period
    1 AS IsActive,            -- Default: Active
    GETDATE() AS CreatedOn
FROM sys.servers s
LEFT JOIN [DBAOpsRepository].[config].[ServerComplianceRules] scr 
    ON s.name = scr.ServerName
WHERE s.is_linked = 1 
    AND scr.ServerName IS NULL;

SET @InsertedCount = @@ROWCOUNT;

-- Log the result
IF @InsertedCount > 0
BEGIN
    SET @Message = ''Added '' + CAST(@InsertedCount AS NVARCHAR(10)) + '' new server(s) to ServerComplianceRules'';
    PRINT @Message;
    
    -- Log to audit table if exists
    IF OBJECT_ID(''DBAOpsRepository.dbo.AuditLog'', ''U'') IS NOT NULL
    BEGIN
        INSERT INTO DBAOpsRepository.dbo.AuditLog (EventType, EventMessage, EventTime)
        VALUES (''CONFIG_SYNC'', @Message, GETDATE());
    END
END
ELSE
BEGIN
    PRINT ''ServerComplianceRules is already in sync with linked servers. No changes needed.'';
END

-- Show current stats
SELECT 
    ''ServerComplianceRules'' AS TableName,
    COUNT(*) AS TotalRules,
    SUM(CASE WHEN IsActive = 1 THEN 1 ELSE 0 END) AS ActiveRules
FROM [DBAOpsRepository].[config].[ServerComplianceRules];
', @on_success_action = 3, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Sync ServerComplianceRules', @step_name = 'Report Orphaned Rules (servers removed)', @step_id = 2, @subsystem = 'TSQL', @command = '
/*
================================================================================
Report Orphaned ServerComplianceRules (linked servers that were removed)
- Does NOT delete them automatically (manual review recommended)
================================================================================
*/
SET NOCOUNT ON;

DECLARE @OrphanCount INT;

SELECT @OrphanCount = COUNT(*)
FROM [DBAOpsRepository].[config].[ServerComplianceRules] scr
LEFT JOIN sys.servers s ON scr.ServerName = s.name
WHERE s.name IS NULL;

IF @OrphanCount > 0
BEGIN
    PRINT ''WARNING: Found '' + CAST(@OrphanCount AS NVARCHAR(10)) + '' orphaned rule(s) - linked server no longer exists:'';
    PRINT '''';
    
    SELECT 
        scr.RuleID,
        scr.ServerName AS OrphanedServer,
        scr.CreatedOn,
        ''Linked server not found'' AS Status
    FROM [DBAOpsRepository].[config].[ServerComplianceRules] scr
    LEFT JOIN sys.servers s ON scr.ServerName = s.name
    WHERE s.name IS NULL;
    
    PRINT '''';
    PRINT ''Review these entries and manually delete if server is decommissioned.'';
    PRINT ''DELETE FROM [DBAOpsRepository].[config].[ServerComplianceRules] WHERE ServerName = ''''<ServerName>'''''';
END
ELSE
BEGIN
    PRINT ''No orphaned rules found. All ServerComplianceRules entries have corresponding linked servers.'';
END
', @on_success_action = 3, @on_fail_action = 3;
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Sync ServerComplianceRules', @step_name = 'Verification Summary', @step_id = 3, @subsystem = 'TSQL', @command = '
/*
================================================================================
Final Verification Summary
================================================================================
*/
SET NOCOUNT ON;

PRINT ''================================================================'';
PRINT ''ServerComplianceRules Sync - Verification Summary'';
PRINT ''================================================================'';
PRINT '''';

-- Linked servers count
DECLARE @LinkedCount INT, @RulesCount INT, @MissingCount INT;

SELECT @LinkedCount = COUNT(*) FROM sys.servers WHERE is_linked = 1;
SELECT @RulesCount = COUNT(*) FROM [DBAOpsRepository].[config].[ServerComplianceRules];
SELECT @MissingCount = COUNT(*)
FROM sys.servers s
LEFT JOIN [DBAOpsRepository].[config].[ServerComplianceRules] scr ON s.name = scr.ServerName
WHERE s.is_linked = 1 AND scr.ServerName IS NULL;

PRINT ''Linked Servers:          '' + CAST(@LinkedCount AS NVARCHAR(10));
PRINT ''ServerComplianceRules:   '' + CAST(@RulesCount AS NVARCHAR(10));
PRINT ''Missing from Rules:      '' + CAST(@MissingCount AS NVARCHAR(10));
PRINT '''';

IF @MissingCount = 0
    PRINT ''âœ“ All linked servers are covered by ServerComplianceRules'';
ELSE
    PRINT ''âœ— WARNING: '' + CAST(@MissingCount AS NVARCHAR(10)) + '' linked server(s) missing from rules'';

PRINT '''';
PRINT ''================================================================'';
PRINT ''Sync completed at: '' + CONVERT(VARCHAR, GETDATE(), 120);
PRINT ''================================================================'';
', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Sync ServerComplianceRules', @name = 'Daily 6:00 AM - Before Compliance Reports', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 1, @freq_subday_interval = 0, @active_start_time = 60000;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Sync ServerComplianceRules', @server_name = '(local)';
GO

-- === DBAOps - Sync ServerInventory from CMS ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Sync ServerInventory from CMS')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Sync ServerInventory from CMS', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Sync ServerInventory from CMS', @enabled = 1, @description = 'Syncs config.ServerInventory table from CMS (source of truth). This allows legacy procedures to continue working while CMS remains authoritative.', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Sync ServerInventory from CMS', @step_name = 'Sync from CMS (All Tables)', @step_id = 1, @subsystem = 'TSQL', @command = 'EXEC config.usp_SyncFromCMS @DebugMode = 0;', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Sync ServerInventory from CMS', @name = 'Hourly', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 8, @freq_subday_interval = 1, @active_start_time = 0;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Sync ServerInventory from CMS', @server_name = '(local)';
GO

-- === DBAOps - System DB Full Backup ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - System DB Full Backup')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - System DB Full Backup', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - System DB Full Backup', @enabled = 1, @description = 'No description available.', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - System DB Full Backup', @step_name = 'Backup System Databases', @step_id = 1, @subsystem = 'TSQL', @command = '
-- System Database Full Backup
-- Backs up master, model, and msdb databases

DECLARE @BackupPath NVARCHAR(500) = N''E:\SQLBackups\SystemDBs\'';  -- Adjust path as needed
DECLARE @DateSuffix NVARCHAR(20) = FORMAT(GETDATE(), ''yyyyMMdd_HHmmss'');
DECLARE @BackupFile NVARCHAR(500);

-- Create backup directory if it does not exist
EXEC master.dbo.xp_create_subdir @BackupPath;

-- Backup master
SET @BackupFile = @BackupPath + N''master_FULL_'' + @DateSuffix + N''.bak'';
BACKUP DATABASE [master] TO DISK = @BackupFile
WITH COMPRESSION, CHECKSUM, STATS = 10;
PRINT ''master backup completed: '' + @BackupFile;

-- Backup model
SET @BackupFile = @BackupPath + N''model_FULL_'' + @DateSuffix + N''.bak'';
BACKUP DATABASE [model] TO DISK = @BackupFile
WITH COMPRESSION, CHECKSUM, STATS = 10;
PRINT ''model backup completed: '' + @BackupFile;

-- Backup msdb
SET @BackupFile = @BackupPath + N''msdb_FULL_'' + @DateSuffix + N''.bak'';
BACKUP DATABASE [msdb] TO DISK = @BackupFile
WITH COMPRESSION, CHECKSUM, STATS = 10;
PRINT ''msdb backup completed: '' + @BackupFile;

PRINT ''All system database backups completed successfully.'';
', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - System DB Full Backup', @name = 'Daily at 2:00 AM', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 1, @freq_subday_interval = 0, @active_start_time = 20000;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - System DB Full Backup', @server_name = '(local)';
GO

-- === DBAOps - System Protection ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - System Protection')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - System Protection', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - System Protection', @enabled = 1, @description = 'Daily health check, integrity scan, and full backup of DBAOps Enterprise™ system', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - System Protection', @step_name = 'Run Full Protection Suite', @step_id = 1, @subsystem = 'PowerShell', @command = '& "{{InstallPath}}\Scripts\Protect-DBAOpsUltimate.ps1" -All', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - System Protection', @name = 'Daily 11 PM', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 1, @freq_subday_interval = 0, @active_start_time = 230000;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - System Protection', @server_name = '(local)';
GO

-- === DBAOps - Throttle External Processes ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Throttle External Processes')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Throttle External Processes', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Throttle External Processes', @enabled = 1, @description = 'Automatically throttle Tanium/Elastic/Veeam agents when SQL Server CPU exceeds threshold.', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Throttle External Processes', @step_name = 'Evaluate Throttle Requirements', @step_id = 1, @subsystem = 'TSQL', @command = 'EXEC DBAOpsRepository.control.usp_EvaluateExternalProcessThrottling @DebugMode = 0;', @on_success_action = 3, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Throttle External Processes', @step_name = 'Execute Remote Throttle Commands', @step_id = 2, @subsystem = 'PowerShell', @command = '& "{{InstallPath}}\Scripts\DBAOps_ThrottleExternalProcesses.ps1" -DBAOpsServer $env:COMPUTERNAME -Database "DBAOpsRepository"', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Throttle External Processes', @name = 'Every 5 Minutes - Throttle Evaluation', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 4, @freq_subday_interval = 5, @active_start_time = 0;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Throttle External Processes', @server_name = '(local)';
GO

-- === DBAOps - Track Config Changes ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Track Config Changes')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Track Config Changes', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Track Config Changes', @enabled = 1, @description = 'Track server configuration changes', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Track Config Changes', @step_name = 'Execute', @step_id = 1, @subsystem = 'TSQL', @command = 'EXEC change.usp_TrackConfigChanges;', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Track Config Changes', @name = 'DBAOps - Track Config Changes Schedule', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 1, @freq_subday_interval = 0, @active_start_time = 40000;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Track Config Changes', @server_name = '(local)';
GO

-- === DBAOps - TRACS Daily Health Report ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - TRACS Daily Health Report')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - TRACS Daily Health Report', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - TRACS Daily Health Report', @enabled = 1, @description = 'Sends daily single-sentence TRACS health summary', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - TRACS Daily Health Report', @step_name = 'Send Daily Report', @step_id = 1, @subsystem = 'TSQL', @command = 'EXEC DBAOpsRepository.TRACS.usp_DailyHealthReport;', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - TRACS Daily Health Report', @name = 'TRACS Daily Report 7AM', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 1, @freq_subday_interval = 0, @active_start_time = 70000;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - TRACS Daily Health Report', @server_name = '(local)';
GO

-- === DBAOps - TRACS Performance Collection ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - TRACS Performance Collection')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - TRACS Performance Collection', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - TRACS Performance Collection', @enabled = 1, @description = 'Collects performance metrics from TRACS servers every minute for vendor inquiry support and capacity planning.', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - TRACS Performance Collection', @step_name = 'Collect TRACS Metrics', @step_id = 1, @subsystem = 'TSQL', @command = 'EXEC DBAOpsRepository.TRACS.usp_CollectTRACSMetrics;', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - TRACS Performance Collection', @name = 'Every 30 Minutes', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 4, @freq_subday_interval = 30, @active_start_time = 0;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - TRACS Performance Collection', @server_name = '(local)';
GO

-- === DBAOps â€“ Unified Compliance Report (Hourly) ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps â€“ Unified Compliance Report (Hourly)')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps â€“ Unified Compliance Report (Hourly)', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps â€“ Unified Compliance Report (Hourly)', @enabled = 1, @description = 'Hourly CJIS/NIST/DISA compliance report. Author: RHOYLLE INNOVATION EMPIRE LLC', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Unified Compliance Report (Hourly)', @step_name = 'Send Compliance Report', @step_id = 1, @subsystem = 'TSQL', @command = 'EXEC DBAOpsRepository.alert.usp_UnifiedComplianceReport @SendEmail = 1;', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps â€“ Unified Compliance Report (Hourly)', @name = 'DBAOps_Hourly_Compliance', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 8, @freq_subday_interval = 1, @active_start_time = 0;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps â€“ Unified Compliance Report (Hourly)', @server_name = '(local)';
GO

-- === DBAOps â€“ Universal Health Engine ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps â€“ Universal Health Engine')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps â€“ Universal Health Engine', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps â€“ Universal Health Engine', @enabled = 1, @description = 'Runs the Universal Health Check every 5 minutes.', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Universal Health Engine', @step_name = 'Execute Universal Health Check', @step_id = 1, @subsystem = 'TSQL', @command = 'EXEC DBAOpsRepository.dbo.usp_DBAOps_UniversalHealthCheck_vFinal;', @on_success_action = 1, @on_fail_action = 4;
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Universal Health Engine', @step_name = 'Send Failure Alert', @step_id = 2, @subsystem = 'TSQL', @command = '
EXEC msdb.dbo.sp_send_dbmail
    @profile_name = ''DBAOpsProfile'',
    @recipients   = ''dbaops@yourdomain.com'',
    @subject      = ''*** SQL ALERT: Job Failure â€“ $(ESCAPE_NONE(JOBNAME)) ***'',
    @body         = ''SQL Agent detected a failure in job "$(ESCAPE_NONE(JOBNAME))" on server "$(ESCAPE_NONE(SRVR))".'',
    @body_format  = ''TEXT'';
', @on_success_action = 1, @on_fail_action = 1;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps â€“ Universal Health Engine', @name = 'DBAOps_Every5Min_HealthEngine_2025-12-04 14-17-45', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 4, @freq_subday_interval = 5, @active_start_time = 0;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps â€“ Universal Health Engine', @server_name = '(local)';
GO

-- === DBAOps â€“ Universal Health Report (Hourly) ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps â€“ Universal Health Report (Hourly)')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps â€“ Universal Health Report (Hourly)', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps â€“ Universal Health Report (Hourly)', @enabled = 1, @description = 'Sends hourly HTML health report with CJIS/NIST/DISA compliance. Author: RHOYLLE INNOVATION EMPIRE LLC', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Universal Health Report (Hourly)', @step_name = 'Generate Hourly Report', @step_id = 1, @subsystem = 'TSQL', @command = 'EXEC DBAOpsRepository.alert.usp_UniversalHealthReport @ReportType = ''HOURLY'', @SendEmail = 1;', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps â€“ Universal Health Report (Hourly)', @name = 'DBAOps_HealthReport_Hourly', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 8, @freq_subday_interval = 1, @active_start_time = 0;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps â€“ Universal Health Report (Hourly)', @server_name = '(local)';
GO

-- === DBAOps â€“ Update Forecast ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps â€“ Update Forecast')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps â€“ Update Forecast', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps â€“ Update Forecast', @enabled = 1, @description = 'No description available.', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Update Forecast', @step_name = 'Run Forecast Model', @step_id = 1, @subsystem = 'TSQL', @command = 'EXEC metrics.usp_UpdateForecastSimple;', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps â€“ Update Forecast', @name = 'Daily at 5AM', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 1, @freq_subday_interval = 0, @active_start_time = 50000;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps â€“ Update Forecast', @server_name = '(local)';
GO

-- === DBAOps â€“ Validate Log Directories ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps â€“ Validate Log Directories')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps â€“ Validate Log Directories', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps â€“ Validate Log Directories', @enabled = 1, @description = 'Ensures {{InstallPath}}\Logs structure exists and is writable.', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Validate Log Directories', @step_name = 'Create Directories', @step_id = 1, @subsystem = 'PowerShell', @command = '
$paths = @(
    "{{InstallPath}}\Logs",
    "{{InstallPath}}\Logs\SQLAgent",
    "{{InstallPath}}\Logs\Collectors",
    "{{InstallPath}}\Logs\Errors"
)
foreach ($p in $paths) { if (-not (Test-Path $p)) { New-Item -Path $p -ItemType Directory -Force | Out-Null } }
', @on_success_action = 1, @on_fail_action = 4;
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Validate Log Directories', @step_name = 'Send Failure Alert', @step_id = 2, @subsystem = 'TSQL', @command = '
EXEC msdb.dbo.sp_send_dbmail
    @profile_name = ''DBAOpsProfile'',
    @recipients   = ''dbaops@yourdomain.com'',
    @subject      = ''*** SQL ALERT: Job Failure â€“ $(ESCAPE_NONE(JOBNAME)) ***'',
    @body         = ''SQL Agent detected a failure in job "$(ESCAPE_NONE(JOBNAME))" on server "$(ESCAPE_NONE(SRVR))".'',
    @body_format  = ''TEXT'';
', @on_success_action = 1, @on_fail_action = 1;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps â€“ Validate Log Directories', @name = 'DBAOps - Daily 5AM Log Validation', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 1, @freq_subday_interval = 0, @active_start_time = 50000;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps â€“ Validate Log Directories', @server_name = '(local)';
GO

-- === DBAOps - Veeam Backup Alerts ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Veeam Backup Alerts')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Veeam Backup Alerts', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Veeam Backup Alerts', @enabled = 1, @description = 'Sends email alerts for Veeam backup failures', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Veeam Backup Alerts', @step_name = 'Send Veeam Alerts', @step_id = 1, @subsystem = 'TSQL', @command = 'EXEC DBAOpsRepository.alert.usp_SendVeeamBackupAlerts;', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Veeam Backup Alerts', @name = 'Every 15 minutes - Veeam Alerts', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 4, @freq_subday_interval = 15, @active_start_time = 0;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Veeam Backup Alerts', @server_name = '(local)';
GO

-- === DBAOps â€“ Veeam ETL Cleanup ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps â€“ Veeam ETL Cleanup')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps â€“ Veeam ETL Cleanup', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps â€“ Veeam ETL Cleanup', @enabled = 1, @description = 'Deletes rows older than 30 days from etl.VeeamBackups and logs results.', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Veeam ETL Cleanup', @step_name = 'Cleanup Old Veeam Backup Metadata', @step_id = 1, @subsystem = 'TSQL', @command = 'EXEC etl.Cleanup_VeeamBackups;', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps â€“ Veeam ETL Cleanup', @name = 'Daily Cleanup at 1 AM', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 1, @freq_subday_interval = 0, @active_start_time = 10000;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps â€“ Veeam ETL Cleanup', @server_name = '(local)';
GO

-- === DBAOps - Wednesday Release Detection ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Wednesday Release Detection')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Wednesday Release Detection', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Wednesday Release Detection', @enabled = 1, @description = 'DBAOps Monitoring and Compliance Framework - Checks for new Microsoft SQL Server releases every Wednesday (day after Patch Tuesday) and sends notification with approval script. Author: RHOYLLE INNOVATION EMPIRE LLC', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Wednesday Release Detection', @step_name = 'Check for New Microsoft Releases', @step_id = 1, @subsystem = 'TSQL', @command = 'EXEC Patching.usp_CheckAndNotifyNewReleases;', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Wednesday Release Detection', @name = 'Weekly Wednesday 8AM - Release Detection', @freq_type = 8, @freq_interval = 4, @freq_subday_type = 1, @freq_subday_interval = 0, @active_start_time = 80000;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Wednesday Release Detection', @server_name = '(local)';
GO

-- === DBAOps - Weekly Cleanup ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Weekly Cleanup')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Weekly Cleanup', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Weekly Cleanup', @enabled = 1, @description = 'Weekly cleanup of old correlation data, timeline events, and archived evidence.', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Weekly Cleanup', @step_name = 'Cleanup Correlation Data', @step_id = 1, @subsystem = 'TSQL', @command = '
-- Archive resolved incidents older than 90 days
UPDATE correlation.Incidents
SET Status = ''Archived''
WHERE Status = ''Resolved'' 
  AND ResolvedDate < DATEADD(DAY, -90, GETDATE());

PRINT CONCAT(''Incidents archived: '', @@ROWCOUNT);

-- Remove very old fingerprints
DELETE FROM correlation.Fingerprints
WHERE IsActive = 0 AND LastSeenDate < DATEADD(DAY, -180, GETDATE());

PRINT CONCAT(''Old fingerprints removed: '', @@ROWCOUNT);', @on_success_action = 3, @on_fail_action = 3;
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Weekly Cleanup', @step_name = 'Cleanup Timeline Data', @step_id = 2, @subsystem = 'TSQL', @command = '
-- Archive timeline events older than 1 year
DELETE FROM change.UnifiedTimeline
WHERE ChangeDateTime < DATEADD(YEAR, -1, GETDATE());

PRINT CONCAT(''Timeline events cleaned: '', @@ROWCOUNT);', @on_success_action = 3, @on_fail_action = 3;
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Weekly Cleanup', @step_name = 'Archive Old Evidence', @step_id = 3, @subsystem = 'TSQL', @command = '
-- Mark expired evidence as archived
UPDATE compliance.EvidenceStore
SET IsArchived = 1
WHERE ValidUntil < GETDATE() AND IsArchived = 0;

PRINT CONCAT(''Evidence archived: '', @@ROWCOUNT);

-- Delete very old archived evidence (keep 2 years for audits)
DELETE FROM compliance.EvidenceStore
WHERE IsArchived = 1 AND CollectionDateTime < DATEADD(YEAR, -2, GETDATE());

PRINT CONCAT(''Old evidence removed: '', @@ROWCOUNT);', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Weekly Cleanup', @name = 'Weekly_Sunday0200', @freq_type = 8, @freq_interval = 1, @freq_subday_type = 1, @freq_subday_interval = 0, @active_start_time = 20000;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Weekly Cleanup', @server_name = '(local)';
GO

-- === DBAOps â€“ Weekly Critical Server Report ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps â€“ Weekly Critical Server Report')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps â€“ Weekly Critical Server Report', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps â€“ Weekly Critical Server Report', @enabled = 1, @description = 'Generates a weekly Word document report of critical server issues including disk space and memory pressure. Runs every Monday at 7:00 AM.', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Weekly Critical Server Report', @step_name = 'Generate Weekly Report', @step_id = 1, @subsystem = 'CmdExec', @command = 'cmd /c powershell.exe -NonInteractive -ExecutionPolicy Bypass -File "{{InstallPath}}\Scripts\Generate-WeeklyCriticalServerReport-v3.ps1" > "{{InstallPath}}\Logs\WeeklyReport.log" 2>&1', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps â€“ Weekly Critical Server Report', @name = 'Weekly Monday 7AM', @freq_type = 8, @freq_interval = 2, @freq_subday_type = 1, @freq_subday_interval = 0, @active_start_time = 70000;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps â€“ Weekly Critical Server Report', @server_name = '(local)';
GO

-- === DBAOps - Weekly EOS Report ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Weekly EOS Report')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Weekly EOS Report', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Weekly EOS Report', @enabled = 1, @description = 'Weekly SQL Server End of Service report - alerts on servers approaching or past EOS dates. Part of DBAOps Monitoring Framework.', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Weekly EOS Report', @step_name = 'Send EOS Report', @step_id = 1, @subsystem = 'TSQL', @command = 'EXEC [DBAOpsRepository].[dbo].[usp_Send_EOS_WeeklyReport] 
    @Recipients = ''dbaops@yourdomain.com'',
    @SendIfNoIssues = 0', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Weekly EOS Report', @name = 'Weekly Monday 8AM', @freq_type = 8, @freq_interval = 2, @freq_subday_type = 1, @freq_subday_interval = 0, @active_start_time = 80000;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Weekly EOS Report', @server_name = '(local)';
GO

-- === DBAOps - Weekly Patching Intelligence Report ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Weekly Patching Intelligence Report')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Weekly Patching Intelligence Report', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Weekly Patching Intelligence Report', @enabled = 1, @description = 'DBAOps Monitoring and Compliance Framework - Weekly Monday patching intelligence report with Microsoft release tracking, patch schedules, and compliance status. Author: RHOYLLE INNOVATION EMPIRE LLC', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Weekly Patching Intelligence Report', @step_name = 'Update Compliance Data', @step_id = 1, @subsystem = 'TSQL', @command = 'EXEC Patching.usp_UpdateComplianceStatus; EXEC Patching.usp_UpdateTaniumCompliance;', @on_success_action = 3, @on_fail_action = 3;
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Weekly Patching Intelligence Report', @step_name = 'Generate Weekly Patching Intelligence Report', @step_id = 2, @subsystem = 'TSQL', @command = 'EXEC Patching.usp_GenerateWeeklyPatchReport @SendEmail = 1;', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Weekly Patching Intelligence Report', @name = 'Weekly Monday 7AM - Patching Intelligence', @freq_type = 8, @freq_interval = 2, @freq_subday_type = 1, @freq_subday_interval = 0, @active_start_time = 70000;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Weekly Patching Intelligence Report', @server_name = '(local)';
GO

-- === DBAOps â€“ Weekly SQL Inventory Report ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps â€“ Weekly SQL Inventory Report')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps â€“ Weekly SQL Inventory Report', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps â€“ Weekly SQL Inventory Report', @enabled = 1, @description = 'Sends weekly SQL inventory report via HTML email', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Weekly SQL Inventory Report', @step_name = 'Send Inventory Email', @step_id = 1, @subsystem = 'TSQL', @command = 'EXEC ctl.usp_SendServerInventoryReport;', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps â€“ Weekly SQL Inventory Report', @name = 'Weekly Saturday 8PM', @freq_type = 8, @freq_interval = 64, @freq_subday_type = 1, @freq_subday_interval = 0, @active_start_time = 200000;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps â€“ Weekly SQL Inventory Report', @server_name = '(local)';
GO

-- === DBAOps - Weekly SQL Servicing Currency and Support Report ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Weekly SQL Servicing Currency and Support Report')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Weekly SQL Servicing Currency and Support Report', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Weekly SQL Servicing Currency and Support Report', @enabled = 1, @description = 'DBAOps | JB | Weekly SQL servicing currency and lifecycle report (HTML and CSV). Runs every Monday at 7:00 AM.', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Weekly SQL Servicing Currency and Support Report', @step_name = 'Send SQL Servicing Currency Report', @step_id = 1, @subsystem = 'TSQL', @command = 'EXEC report.usp_Email_SqlServicingCurrency_Report 
    @DistributionName = N''DBAOps_SqlServicingWeekly'', 
    @SendEmail = 1, 
    @NearEosDays = 180;', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Weekly SQL Servicing Currency and Support Report', @name = 'DBAOps - Weekly Monday 0700 - SQL Patching Report', @freq_type = 8, @freq_interval = 2, @freq_subday_type = 1, @freq_subday_interval = 0, @active_start_time = 70000;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Weekly SQL Servicing Currency and Support Report', @server_name = '(local)';
GO

-- === DBAOps â€“ Weekly Summary ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps â€“ Weekly Summary')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps â€“ Weekly Summary', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps â€“ Weekly Summary', @enabled = 1, @description = 'Sends weekly summary of DBAOps health, failures, alerts, and trends.', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Weekly Summary', @step_name = 'Execute', @step_id = 1, @subsystem = 'PowerShell', @command = 'PowerShell.exe -NoProfile -ExecutionPolicy Bypass -Command "Import-Module ''{{InstallPath}}\Modules\DBAOps\DBAOps.psm1''; Send-WeeklySummary -Repository $env:COMPUTERNAME -Verbose"', @on_success_action = 1, @on_fail_action = 4;
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Weekly Summary', @step_name = 'Send Failure Alert', @step_id = 2, @subsystem = 'TSQL', @command = '
EXEC msdb.dbo.sp_send_dbmail
    @profile_name = ''DBAOpsProfile'',
    @recipients   = ''dbaops@yourdomain.com'',
    @subject      = ''*** SQL ALERT: Job Failure â€“ $(ESCAPE_NONE(JOBNAME)) ***'',
    @body         = ''SQL Agent detected a failure in job "$(ESCAPE_NONE(JOBNAME))" on server "$(ESCAPE_NONE(SRVR))".'',
    @body_format  = ''TEXT'';
', @on_success_action = 1, @on_fail_action = 1;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps â€“ Weekly Summary', @name = 'Weekly Sunday 6AM', @freq_type = 8, @freq_interval = 1, @freq_subday_type = 1, @freq_subday_interval = 0, @active_start_time = 60000;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps â€“ Weekly Summary', @server_name = '(local)';
GO

-- === DBAOps - Weekly Summary Report ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Weekly Summary Report')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Weekly Summary Report', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Weekly Summary Report', @enabled = 1, @description = 'Weekly audit with historical trending - Monday 8:00 AM.', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Weekly Summary Report', @step_name = 'Run Weekly Audit Report', @step_id = 1, @subsystem = 'TSQL', @command = '
-- Run standard audit
EXEC dbo.usp_DBAOps_EnvironmentAudit
    @EmailReport = 1,
    @EmailRecipients = N''dbaops@yourdomain.com'',
    @EmailProfile = N''DBAOpsProfile'',
    @OutputToTable = 1,
    @PrintHTML = 0,
    @Debug = 0;

-- Send weekly trend if historical data exists
IF OBJECT_ID(''dbo.DBAOps_AuditFindings'', ''U'') IS NOT NULL
BEGIN
    DECLARE @HTML NVARCHAR(MAX);
    DECLARE @Subject NVARCHAR(255) = N''DBAOps Weekly Trend - '' + @@SERVERNAME;
    
    SET @HTML = N''<html><head><style>
        body{font-family:Arial;padding:20px}
        h2{color:#2c3e50}
        table{border-collapse:collapse;width:100%}
        th{background:#34495e;color:white;padding:12px}
        td{padding:10px;border:1px solid #ddd}
        tr:nth-child(even){background:#f9f9f9}
        .crit{color:#e74c3c;font-weight:bold}
        .high{color:#f39c12;font-weight:bold}
    </style></head><body>
    <h2>Weekly Audit Trend (Last 7 Days)</h2>
    <table><tr><th>Date</th><th>Critical</th><th>High</th><th>Medium</th><th>Total</th></tr>'';
    
    SELECT @HTML = @HTML + 
        N''<tr><td>'' + CONVERT(NVARCHAR(10), CAST(AuditRunTime AS DATE)) + 
        N''</td><td class="crit">'' + CAST(SUM(CASE WHEN Severity=''CRITICAL'' THEN 1 ELSE 0 END) AS NVARCHAR) +
        N''</td><td class="high">'' + CAST(SUM(CASE WHEN Severity=''HIGH'' THEN 1 ELSE 0 END) AS NVARCHAR) +
        N''</td><td>'' + CAST(SUM(CASE WHEN Severity=''MEDIUM'' THEN 1 ELSE 0 END) AS NVARCHAR) +
        N''</td><td>'' + CAST(COUNT(*) AS NVARCHAR) + N''</td></tr>''
    FROM dbo.DBAOps_AuditFindings
    WHERE AuditRunTime >= DATEADD(DAY, -7, GETDATE())
    GROUP BY CAST(AuditRunTime AS DATE)
    ORDER BY CAST(AuditRunTime AS DATE) DESC;
    
    SET @HTML = @HTML + N''</table><p style="color:#7f8c8d;font-size:12px">Generated: '' + 
        CONVERT(NVARCHAR(30), GETDATE(), 120) + N''</p></body></html>'';
    
    EXEC msdb.dbo.sp_send_dbmail
        @profile_name = N''DBAOpsProfile'',
        @recipients = N''dbaops@yourdomain.com'',
        @subject = @Subject,
        @body = @HTML,
        @body_format = ''HTML'';
END
', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Weekly Summary Report', @name = 'Monday at 8:00 AM', @freq_type = 8, @freq_interval = 2, @freq_subday_type = 1, @freq_subday_interval = 0, @active_start_time = 80000;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Weekly Summary Report', @server_name = '(local)';
GO

-- === DBAOps - Weekly Tanium SQL Patching Report ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps - Weekly Tanium SQL Patching Report')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps - Weekly Tanium SQL Patching Report', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps - Weekly Tanium SQL Patching Report', @enabled = 1, @description = 'DBAOps Monitoring and Compliance Framework - Weekly Tanium SQL patching compliance report per CJIS/NIST standards. Author: RHOYLLE INNOVATION EMPIRE LLC', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Weekly Tanium SQL Patching Report', @step_name = 'Refresh Compliance Data', @step_id = 1, @subsystem = 'TSQL', @command = 'EXEC Patching.usp_UpdateComplianceStatus; EXEC Patching.usp_UpdateTaniumCompliance;', @on_success_action = 3, @on_fail_action = 3;
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps - Weekly Tanium SQL Patching Report', @step_name = 'Generate and Send Tanium Compliance Report', @step_id = 2, @subsystem = 'TSQL', @command = 'EXEC Patching.usp_GenerateTaniumComplianceReport @SendEmail = 1;', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps - Weekly Tanium SQL Patching Report', @name = 'Weekly Monday 7AM - Tanium Compliance Report', @freq_type = 8, @freq_interval = 2, @freq_subday_type = 1, @freq_subday_interval = 0, @active_start_time = 70000;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps - Weekly Tanium SQL Patching Report', @server_name = '(local)';
GO

-- === DBAOps â€“ Windows Update MU Compliance Collector ===
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = 'DBAOps â€“ Windows Update MU Compliance Collector')
    EXEC msdb.dbo.sp_delete_job @job_name = 'DBAOps â€“ Windows Update MU Compliance Collector', @delete_unused_schedule = 1;
GO
EXEC msdb.dbo.sp_add_job @job_name = 'DBAOps â€“ Windows Update MU Compliance Collector', @enabled = 1, @description = 'Executes the PowerShell Windows Update MU compliance collector script and updates DBAOpsRepository.', @owner_login_name = 'sa';
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Windows Update MU Compliance Collector', @step_name = 'Collect Windows Update MU Compliance', @step_id = 1, @subsystem = 'PowerShell', @command = '
# Force latest PowerShell engine
$PSVersionTable

# Import dbatools
try {
    Import-Module dbatools -Force -ErrorAction Stop
    Write-Output "dbatools module loaded successfully."
}
catch {
    Write-Output "ERROR: Failed to import dbatools module."
    Write-Output $_
    exit 1
}

# Execute compliance script
& "{{InstallPath}}\Scripts\WindowsCompliance\Get-WindowsMUCompliance.ps1"
', @on_success_action = 3, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobstep @job_name = 'DBAOps â€“ Windows Update MU Compliance Collector', @step_name = 'Send Compliance Alert Email', @step_id = 2, @subsystem = 'TSQL', @command = 'EXEC DBAOpsRepository.config.usp_Send_WindowsUpdateComplianceAlert;', @on_success_action = 1, @on_fail_action = 2;
GO
EXEC msdb.dbo.sp_add_jobschedule @job_name = 'DBAOps â€“ Windows Update MU Compliance Collector', @name = 'DBAOps â€“ MU Compliance Schedule', @freq_type = 4, @freq_interval = 1, @freq_subday_type = 8, @freq_subday_interval = 6, @active_start_time = 0;
GO
EXEC msdb.dbo.sp_add_jobserver @job_name = 'DBAOps â€“ Windows Update MU Compliance Collector', @server_name = '(local)';
GO

