Nagios is a great free tool to supervize many many things in IT. SQL Server is one appliation that can be monitored by Nagios. A great plugin check_mssql_health contains many checks from performance counters to space used and connection time (36 checks at the time of writing).
In order to secure checks on databases, you need to create logins, users and roles on every instances and databases you want to monitor. The Consol Labs web site (Nagios pluggins & Addons editor) give you a script to create (and drop if needed) these objects on one MSSQL instance but :
1 - We found some missings elements on the script
2 - We will give you one method to quickly launch your create script on several MSSQL instances easily using MSSQL Central Management Server or SSMS Registered Groups
The original script from Birk Bohne is this one :
declare @dbname varchar(255) declare @check_mssql_health_USER varchar(255) declare @check_mssql_health_PASS varchar(255) declare @check_mssql_health_ROLE varchar(255) declare @source varchar(255) declare @options varchar(255) declare @backslash int /*******************************************************************/ SET @check_mssql_health_USER = '"[Servername|Domainname]\Username"' SET @check_mssql_health_PASS = 'Password' SET @check_mssql_health_ROLE = 'Rolename' /****************************************************************** PLEASE CHANGE THE ABOVE VALUES ACCORDING TO YOUR REQUIREMENTS - Example for Windows authentication: SET @check_mssql_health_USER = '"[Servername|Domainname]\Username"' SET @check_mssql_health_ROLE = 'Rolename' - Example for SQL Server authentication: SET @check_mssql_health_USER = 'Username' SET @check_mssql_health_PASS = 'Password' SET @check_mssql_health_ROLE = 'Rolename' !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! It is strongly recommended to use Windows authentication. Otherwise you will get no reliable results for database usage. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! *********** NO NEED TO CHANGE ANYTHING BELOW THIS LINE *************/ SET @options = 'DEFAULT_DATABASE=MASTER, DEFAULT_LANGUAGE=English' SET @backslash = (SELECT CHARINDEX('\', @check_mssql_health_USER)) IF @backslash > 0 BEGIN SET @source = ' FROM WINDOWS' SET @options = ' WITH ' + @options END ELSE BEGIN SET @source = '' SET @options = ' WITH PASSWORD=''' + @check_mssql_health_PASS + ''',' + @options END PRINT 'create Nagios plugin user ' + @check_mssql_health_USER EXEC ('CREATE LOGIN ' + @check_mssql_health_USER + @source + @options) EXEC ('USE MASTER GRANT VIEW SERVER STATE TO ' + @check_mssql_health_USER) EXEC ('USE MASTER GRANT ALTER trace TO ' + @check_mssql_health_USER) EXEC ('USE MSDB GRANT SELECT ON sysjobhistory TO ' + @check_mssql_health_USER) EXEC ('USE MSDB GRANT SELECT ON sysjobschedules TO ' + @check_mssql_health_USER) EXEC ('USE MSDB GRANT SELECT ON sysjobs TO ' + @check_mssql_health_USER) PRINT 'User ' + @check_mssql_health_USER + ' created.' PRINT '' declare dblist cursor for select name from sysdatabases WHERE name NOT IN ('master', 'tempdb', 'msdb') open dblist fetch next from dblist into @dbname while @@fetch_status = 0 begin EXEC ('USE [' + @dbname + '] print ''Grant permissions in the db '' + ''"'' + DB_NAME() + ''"''') EXEC ('USE [' + @dbname + '] CREATE ROLE ' + @check_mssql_health_ROLE) EXEC ('USE [' + @dbname + '] GRANT EXECUTE TO ' + @check_mssql_health_ROLE) EXEC ('USE [' + @dbname + '] GRANT VIEW DATABASE STATE TO ' + @check_mssql_health_ROLE) EXEC ('USE [' + @dbname + '] GRANT VIEW DEFINITION TO ' + @check_mssql_health_ROLE) EXEC ('USE [' + @dbname + '] CREATE USER ' + @check_mssql_health_USER + ' FOR LOGIN ' + @check_mssql_health_USER) EXEC ('USE [' + @dbname + '] EXEC sp_addrolemember ' + @check_mssql_health_ROLE + ' , ' + @check_mssql_health_USER) EXEC ('USE [' + @dbname + '] print ''Permissions in the db '' + ''"'' + DB_NAME() + ''" granted.''') fetch next from dblist into @dbname end close dblist deallocate dblist
The script we use
declare @dbname varchar(255) declare @check_mssql_health_USER varchar(255) declare @check_mssql_health_PASS varchar(255) declare @check_mssql_health_ROLE varchar(255) declare @source varchar(255) declare @options varchar(255) declare @backslash int /*******************************************************************/ SET @check_mssql_health_USER = 'nagios' SET @check_mssql_health_PASS = '**nagios1234password**' SET @check_mssql_health_ROLE = 'monitoring' /******************************************************************/ /*********** NO NEED TO CHANGE ANYTHING BELOW THIS LINE *************/ SET @options = 'DEFAULT_DATABASE=MASTER, DEFAULT_LANGUAGE=English' SET @backslash = (SELECT CHARINDEX('\', @check_mssql_health_USER)) IF @backslash > 0 BEGIN SET @source = ' FROM WINDOWS' SET @options = ' WITH ' + @options END ELSE BEGIN SET @source = '' SET @options = ' WITH PASSWORD=''' + @check_mssql_health_PASS + ''',' + @options END PRINT 'create Nagios plugin user ' + @check_mssql_health_USER EXEC ('CREATE LOGIN ' + @check_mssql_health_USER + @source + @options) EXEC ('USE MASTER GRANT VIEW SERVER STATE TO ' + @check_mssql_health_USER) EXEC ('USE MASTER GRANT ALTER trace TO ' + @check_mssql_health_USER) EXEC ('USE MASTER GRANT VIEW ANY DEFINITION TO ' + @check_mssql_health_USER) EXEC ('USE MSDB CREATE USER ' + @check_mssql_health_USER + ' FOR LOGIN ' + @check_mssql_health_USER) EXEC ('USE MSDB EXEC sp_addrolemember ''db_datareader'' , ''' + @check_mssql_health_USER+'''') --EXEC ('USE MSDB GRANT SELECT ON sysjobhistory TO ' + @check_mssql_health_USER) --EXEC ('USE MSDB GRANT SELECT ON sysjobschedules TO ' + @check_mssql_health_USER) --EXEC ('USE MSDB GRANT SELECT ON sysjobs TO ' + @check_mssql_health_USER) PRINT 'User ' + @check_mssql_health_USER + ' created.' PRINT '' declare dblist cursor for select name from sysdatabases WHERE name NOT IN ('master', 'tempdb', 'msdb') open dblist fetch next from dblist into @dbname while @@fetch_status = 0 begin EXEC ('USE [' + @dbname + '] print ''Grant permissions in the db '' + ''"'' + DB_NAME() + ''"''') EXEC ('USE [' + @dbname + '] CREATE ROLE ' + @check_mssql_health_ROLE) EXEC ('USE [' + @dbname + '] GRANT EXECUTE TO ' + @check_mssql_health_ROLE) EXEC ('USE [' + @dbname + '] GRANT VIEW DATABASE STATE TO ' + @check_mssql_health_ROLE) EXEC ('USE [' + @dbname + '] GRANT VIEW DEFINITION TO ' + @check_mssql_health_ROLE) EXEC ('USE [' + @dbname + '] CREATE USER ' + @check_mssql_health_USER + ' FOR LOGIN ' + @check_mssql_health_USER) EXEC ('USE [' + @dbname + '] EXEC sp_addrolemember ''' + @check_mssql_health_ROLE + ''' , ''' + @check_mssql_health_USER+'''') EXEC ('USE [' + @dbname + '] print ''Permissions in the db '' + ''"'' + DB_NAME() + ''" granted.''') fetch next from dblist into @dbname end close dblist deallocate dblist
The changes are :
we add EXEC ('USE MASTER GRANT VIEW ANY DEFINITION TO ' + @check_mssql_health_USER) in order to read the master.sys.master_files view and check space left on drive or mount point from OS point of view.
we add EXEC ('USE MSDB CREATE USER ' + @check_mssql_health_USER + ' FOR LOGIN ' + @check_mssql_health_USER) and EXEC ('USE MSDB EXEC sp_addrolemember ''db_datareader'' , ''' + @check_mssql_health_USER+'''') because without them no enought priviledges on msdb database.
we comment lines because we have given enougth priviledges to the user in the previous order :
--EXEC ('USE MSDB GRANT SELECT ON sysjobhistory TO ' + @check_mssql_health_USER) --EXEC ('USE MSDB GRANT SELECT ON sysjobschedules TO ' + @check_mssql_health_USER) --EXEC ('USE MSDB GRANT SELECT ON sysjobs TO ' + @check_mssql_health_USER)
Now we need to run the script using the feature of SQL Server Central Management Server (windows authentification only) or local server groups (windows and sql server authentication) : In our case we use a VM with an SSMS installation and we are able to connect to several groups and sub groups we have defined along the time.
Just choose the groups of server where you want to deploy you creation script, and with a right clic choose "New Query". Paste you code and run it. It will run on all registered servers defined in the group and sub-groups. !!