Quantcast
Channel: THWACK: Message List
Viewing all articles
Browse latest Browse all 20019

SQL Version Information Stored Procedure

$
0
0

I am creating a stored procedure to iterate all servers linked to the current server and grab the version information as pulled from the remote server.  This method is probably not the most efficient way to walk all discoverable servers in the environment, yet, I am looking to perform a nested sp_executesql.  This has proven to be the most difficult task to cleanly achieve.  This mainly solves auditors asking to SEE us obtain the server information and not just handing it to them.  Let me know if there is a more optimized way of grabbing as many servers at once in real time as possible.

 

USE [DatabaseName]
GO


SET ANSI_NULLS ON
GO


SET QUOTED_IDENTIFIER ON
GO


--/* ********************************************************************************************
--  Create Scaffold for stored procedure if it does not exist on this server.
--  This ensures that any future changes to this stored procedure can be cleanly
--  submitted without removing any currently set security on existing stored
--  procedure.  This will also will create new stored procedures as needed by
--  creating the dummy SP shown below and then updating the stored procedure
--  afterwards.  The best practice here is to not lose any security settings
--  applied to this procedure once its configured for this server.  Custom schemas
--  enable cleaner security configurations that can be managed without specific
--  user based dependencies of older versions of SQL server.
******************************************************************************************** */
IF NOT EXISTS (  SELECT  schema_name  FROM  INFORMATION_SCHEMA.SCHEMATA  WHERE  schema_name = 'sec'  )
BEGIN  EXEC sp_executesql N'CREATE SCHEMA sec'
END


IF OBJECT_ID(N'[sec].[sp_Server_VersionInformation]') IS NULL
  EXEC ('CREATE PROCEDURE [sec].[sp_Server_VersionInformation] AS BEGIN SET NOCOUNT ON; END')
GO


--/*********************************************************************************************
--©2015 David Tawater
--
--
--STORED PROCEDURE
--  Server_VersionInformation v1.4.0
--
--
--DESCRIPTION
--  Discovers and returns the SQL Server Version, Edition, Service Pack and Product Name
--  information from the currently connected server if RemoteCheck is false.  If RemoteCheck
--  is true then all linked servers will be issued serverproperty function calls to return
--  their server version properties as well.
--
--
--
--
--PARAMETERS
--  @RemoteCheck BIT = 0 : Check linked servers registered on this sql server
--
--
--RETURN VALUES
--  SQL Server Name VARCHAR(64)
--  SQL Server Datasource VARCHAR(64)
--  SQL Server Version VARCHAR(64)
--  SQL Server Edition VARCHAR(64)
--
--PROGRAMMING NOTES
--  SQL Server version details provided by Microsoft Support Link
--  https://support.microsoft.com/kb/321185
--
--CHANGE HISTORY
--Date Version DESCRIPTION
------------------------------------------------------------------------------------------------
--09/05/2014 1.0.0    First Commit
--03/02/2015 1.1.0    Added Service Pack and Edition
--03/02/2015 1.2.1    Corrected Data Types, Added product name detection
--03/03/2015 1.3.0    Added Remote Server Functionality
--03/04/2015 1.4.0    Refactored to handle a list of servers to ignore (Fix ADSI bug)
--
--*********************************************************************************************/


ALTER PROCEDURE [sec].[sp_Server_VersionInformation]
  -- Add the parameters for the stored procedure here  @RemoteCheck BIT = 0
AS
BEGIN  -- SET NOCOUNT ON added to prevent extra result sets from  -- interfering with SELECT statements.  SET NOCOUNT ON;  DECLARE  @ServerID INT = -1  ,@ServersFound INT = 0  ,@Command NVARCHAR(MAX) = ''  ,@ServerName NVARCHAR(MAX) = ''  ,@SourceName NVARCHAR(MAX) = ''  ,@ErrorNumber INT = 0  ,@ErrorMessage NVARCHAR(MAX) = ''  ,@TempVarchar VARCHAR(MAX)  ,@ProductVersion SQL_VARIANT  ,@ProductLevel SQL_VARIANT  ,@ProductEdition SQL_VARIANT  ,@ProductName VARCHAR(64)  ,@ProductVersionNum INT  ,@ProductRevisionNum INT;  DECLARE  @Excluded TABLE (  RecordID BIGINT IDENTITY (1,1) PRIMARY KEY  ,ServerName SYSNAME  )  INSERT INTO @Excluded (ServerName)  VALUES ('ADSI') --Active Directory, Not a SQL Server  ,('RandomServer') --Example Server, Ignore  ,('SomeServer2') --Example other kind of Server, Ignore  DECLARE  @Results AS TABLE (  ServerName VARCHAR(64)  ,SourceName VARCHAR(64)  ,ProductName VARCHAR(64)  ,ProductEdition VARCHAR(64)  )  IF @RemoteCheck = 0  BEGIN  SELECT  @ProductVersion = CAST(SERVERPROPERTY('productversion') AS VARCHAR(64))  ,@ProductLevel = CAST(SERVERPROPERTY('productlevel') AS VARCHAR(64))  ,@ProductEdition = CAST(SERVERPROPERTY('edition') AS VARCHAR(64))  ,@ServerName = CAST(SERVERPROPERTY('MachineName') AS VARCHAR(64))  ,@SourceName = CAST(SERVERPROPERTY('MachineName') AS VARCHAR(64))  SELECT @TempVarchar = CAST(@ProductVersion AS VARCHAR)  SELECT  @ProductVersionNum = SUBSTRING(@TempVarchar,1,CHARINDEX('.',@TempVarchar) - 1)  ,@ProductRevisionNum = REPLACE(SUBSTRING(@TempVarchar,CHARINDEX('.',@TempVarchar) + 1,CHARINDEX('.',@TempVarchar,CHARINDEX('.',@TempVarchar)) - 1),'.','')  SELECT  @ProductName = 'SQL Server ' +  CASE @ProductVersionNum  WHEN 9 THEN '2005'  WHEN 10 THEN '2008'  WHEN 11 THEN '2012'  WHEN 12 THEN '2014'  END +  CASE @ProductRevisionNum  WHEN 0 THEN ''  WHEN 50 THEN ' R2'  END +  ' ' + CAST(@ProductLevel AS VARCHAR)+  ' ' + CAST(@ProductVersion AS VARCHAR)  INSERT INTO @Results (ServerName,SourceName, ProductName,ProductEdition)  SELECT @ServerName,@SourceName,@ProductName,CAST(@ProductEdition AS VARCHAR)  END  ELSE  BEGIN  -- Iterate over all servers linked  WHILE (1 = 1)  BEGIN  -- Get next servers details  SELECT TOP 1  @ServerID = S.server_id  --This is needed to correct the remote variable not declared error  --Troubleshooting needed to parameterize inside sql paramters to  --pull outside sql paramter values INTO this nested remote execute statement.  -- S.name + '.master.sys.sp_executeSQL  ,@Command = N'EXEC ' + S.name + '.master.sys.sp_executesql  N''SELECT  @ProductVersionINNER = SERVERPROPERTY(''''productversion'''')  ,@ProductLevelINNER = SERVERPROPERTY(''''productlevel'''')  ,@ProductEditionINNER = SERVERPROPERTY(''''edition'''')  ''  ,N''@ProductVersionINNER sql_variant OUTPUT  ,@ProductLevelINNER sql_variant OUTPUT  ,@ProductEditionINNER sql_variant OUTPUT  ''  ,@ProductVersionINNER = @ProductVersionOUTER OUTPUT  ,@ProductLevelINNER = @ProductLevelOUTER OUTPUT  ,@ProductEditionINNER = @ProductEditionOUTER OUTPUT'  ,@ServerName = S.name  ,@SourceName = S.data_source  FROM  sys.servers AS S  LEFT OUTER JOIN @Excluded AS E  ON S.name = E.ServerName  WHERE  S.server_id > @ServerID AND  E.RecordID IS NULL  ORDER BY S.server_id  SET @ServersFound = @@rowcount  --A bit of debug info to research what our script found.  --PRINT 'Servers Found: ' + CAST(@ServersFound AS VARCHAR) + ' Server Name: ' + @ServerName + ' Server ID: ' + CAST(@ServerID AS VARCHAR)  -- Exit loop if no more servers  IF @ServersFound = 0  BREAK  BEGIN TRY  EXEC sys.sp_executesql  @Command  ,N'@ProductVersionOUTER sql_variant OUTPUT  ,@ProductLevelOUTER sql_variant OUTPUT  ,@ProductEditionOUTER sql_variant OUTPUT  '  ,@ProductVersionOUTER = @ProductVersion OUTPUT  ,@ProductLevelOUTER = @ProductLevel OUTPUT  ,@ProductEditionOUTER = @ProductEdition OUTPUT  END TRY  BEGIN CATCH  SET @ErrorNumber = ERROR_NUMBER()  SET @ErrorMessage = ERROR_MESSAGE()  IF @ErrorNumber = 7411  BEGIN  PRINT 'Setting RPC Option ON, rerun procedure again for ' + @ServerName  EXEC sp_serveroption  @server = @ServerName  ,@optname = 'rpc'  ,@optvalue = 'TRUE'  EXEC sp_serveroption  @server = @ServerName  ,@optname = 'rpc out'  ,@optvalue = 'TRUE'  END  ELSE  BEGIN  PRINT 'Error Occured: ' + CAST(@ErrorNumber AS VARCHAR) + ' ' + @ErrorMessage + ' ' + @Command  END  END CATCH  SELECT @TempVarchar = CAST(@ProductVersion AS VARCHAR)  SELECT  @ProductVersionNum = SUBSTRING(@TempVarchar,1,CHARINDEX('.',@TempVarchar) - 1)  ,@ProductRevisionNum = REPLACE(SUBSTRING(@TempVarchar,CHARINDEX('.',@TempVarchar) + 1,CHARINDEX('.',@TempVarchar,CHARINDEX('.',@TempVarchar)) - 1),'.','')  SELECT  @ProductName = 'SQL Server ' +  CASE @ProductVersionNum  WHEN 9 THEN '2005'  WHEN 10 THEN '2008'  WHEN 11 THEN '2012'  WHEN 12 THEN '2014'  END +  CASE @ProductRevisionNum  WHEN 0 THEN ''  WHEN 50 THEN ' R2'  END +  ' ' + CAST(@ProductLevel AS VARCHAR)+  ' ' + CAST(@ProductVersion AS VARCHAR)  INSERT INTO @Results (ServerName,SourceName,ProductName,ProductEdition)  SELECT @ServerName,@SourceName,@ProductName,CAST(@ProductEdition AS VARCHAR)  END  END  SELECT  ServerName AS [Server Name]  ,UPPER(SourceName) AS [Data Source]  ,ProductName AS [Version]  ,ProductEdition AS [Edition]  FROM  @Results



END



 

Message was edited by: David Tawater (Corrected a few readability errors.)


Viewing all articles
Browse latest Browse all 20019

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>