Technical Article

Central Management Server Daily Script

,

As with any script please test these in a development environment before using them against a produciton database server or central management server.

Feel free to post any recommendations and even additional scripts to this to improve the value of these "CMS" morning report scripts.

-HawkeyeDBA

--Purpose: Check servers registered in Central Management Server under
--a grouping like Production_Servers.
--Note: to display each query as one result for all registered servers
--      change Query Options > Results > Multiserver > Merge results to true
--HawkeyeDBA


--Check morning statistics *note: this resets counters at the end to get an accurate--daily reading of wait stats
WITH Waits AS
(SELECT @@SERVERNAME as servername, 
wait_type, wait_time_ms / 1000. AS wait_time_s,
100. * wait_time_ms / SUM(wait_time_ms) OVER() AS pct,
ROW_NUMBER() OVER(ORDER BY wait_time_ms DESC) AS rn
FROM sys.dm_os_wait_stats
WHERE wait_type NOT IN ('CLR_SEMAPHORE','LAZYWRITER_SLEEP','RESOURCE_QUEUE','SLEEP_TASK','SLEEP_SYSTEMTASK','SQLTRACE_BUFFER_FLUSH','WAITFOR', 'LOGMGR_QUEUE','CHECKPOINT_QUEUE','REQUEST_FOR_DEADLOCK_SEARCH','XE_TIMER_EVENT','BROKER_TO_FLUSH','BROKER_TASK_STOP','CLR_MANUAL_EVENT','CLR_AUTO_EVENT','DISPATCHER_QUEUE_SEMAPHORE', 'FT_IFTS_SCHEDULER_IDLE_WAIT','XE_DISPATCHER_WAIT', 'XE_DISPATCHER_JOIN'))

SELECT W1.wait_type, w1.servername,
CAST(W1.wait_time_s AS DECIMAL(12, 2)) AS wait_time_s,
CAST(W1.pct AS DECIMAL(12, 2)) AS pct,
CAST(SUM(W2.pct) AS DECIMAL(12, 2)) AS running_pct
INTO #waitstats
FROM Waits AS W1
INNER JOIN Waits AS W2
ON W2.rn <= W1.rn
GROUP BY W1.rn, W1.wait_type, W1.wait_time_s, W1.pct, W1.servername
HAVING SUM(W2.pct) - W1.pct < 95;  
SELECT GETDATE() as TodaysDate, @@SERVERNAME as servername,
LEFT(SUBSTRING(@@VERSION, PATINDEX('%[2000-2008]%', @@VERSION), LEN(@@VERSION)), 4) SQLVersion,
LEFT(SUBSTRING(@@VERSION, PATINDEX('%[8.00.00-10.50.2500]%', @@VERSION), LEN(@@VERSION)), 25) SQLBuild, 
count(spid) as ProcessCount,
(SELECT MIN(login_time) FROM ..sysprocesses  WHERE loginame NOT LIKE '<list of user logins to exclude - I just use my own') as LastRestart 
INTO #sysinfoFROM ..sysprocesses 
WHERE loginame NOT IN('sa', '<Agent Service account>', '<SQL Service account>') 
SELECT p1.*, ( SELECT + wait_type + ' ' + CONVERT(varchar(50), wait_time_s) + ', '  
               FROM #waitstats p2 
               WHERE p2.servername = p1.servername 
               ORDER BY wait_type FOR XML PATH('') ) AS ColumnList 
FROM #sysinfo p1 
GROUP BY p1.ServerName, p1.TodaysDate, p1.SQLVersion, p1.SQLBuild, p1.ProcessCount, p1.LastRestart;

--cleanup temporary objects
DROP TABLE #waitstats;
DROP TABLE #sysinfo;

--Now clear the wait stats to start accumulation for tomorrow's report
DBCC SQLPERF("sys.dm_os_wait_stats",CLEAR);

--Report failed jobs
SELECT
    @@Servername, 
    b.[name] AS job_name, 
    CONVERT(VARCHAR, a.run_date), 
    a.step_id AS step_number,
    a.step_name, 
    @@ServerName,
    a.run_duration,
    LEFT(a.[message], 255) AS JobMessage
FROM msdb.dbo.sysjobhistory a
INNER JOIN msdb.dbo.sysjobs b ON
    a.job_id = b.job_id
WHERE 
    CONVERT(Varchar, a.run_date) >= CONVERT(Varchar,GetDate() -3, 112) AND
    a.run_status = 0 AND
    a.step_name NOT LIKE '(Job outcome)'


--Report any currently running jobs
SELECT @@servername, b.name as job_name, a.start_execution_date
from msdb..sysjobactivity a
INNER JOIN msdb..sysjobs b on
    a.job_id = b.job_id
WHERE start_execution_date >= GETDATE()-1 and stop_execution_date is NULL;

--Report Missing Backups
--You have to enter the date values for the dynamic sql
--This does NOT look at log backups only full or differential 
CREATE TABLE #BkpDate (BkpDate datetime, dbname varchar(100))

Exec sp_MsForEachDb @command1 = '
Insert into #BkpDate(BkpDate, dbname) VALUES(''05/06/2012'', ''?'')
Insert into #BkpDate(BkpDate, dbname) VALUES(''05/07/2012'', ''?'')
Insert into #BkpDate(BkpDate, dbname) VALUES(''05/08/2012'', ''?'')
--etc...
'
DELETE FROM #BkpDate WHERE dbname in('tempdb', 'model', 'pubs', '<enter any other database you wish to exclude>')
SELECT *
FROM #BkpDate
LEFT JOIN(SELECT 
            CONVERT(varchar, CONVERT(datetime, msdb.dbo.backupset.backup_finish_date, 101), 101) as finish_date,
             msdb.dbo.backupset.database_name, msdb.dbo.backupset.backup_size/1000/1000 as backupsizeMB
            FROM 
                msdb.dbo.backupmediafamily 
            INNER JOIN msdb.dbo.backupset 
            ON msdb.dbo.backupmediafamily.media_set_id = msdb.dbo.backupset.media_set_id
            WHERE msdb..backupset.type LIKE 'D' or msdb..backupset.type LIKE 'I') query ON
BkpDate = finish_date AND
DbName = database_name
 ORDER BY database_name, BkpDate
 
--cleanup temp table
DROP TABLE #BkpDate

--Finally just get a quick glimpse of what is left for drive space, this is not
--meant to "track disk space" rather just to give a quick look
CREATE TABLE #DriveSpace (DriveLetter char(1), MBFree float)
INSERT INTO #DriveSpace
exec xp_fixeddrives;
SELECT DriveLetter, MBFree FROM #DriveSpace;
DROP TABLE #DriveSpace;

Rate

3 (2)

You rated this post out of 5. Change rating

Share

Share

Rate

3 (2)

You rated this post out of 5. Change rating