Scripting SQL Server 2005 Logins

I thought today I would share with you a great way to move SQL Server logins from one SQL Server 2005 server (source) to another SQL Server 2005 server (destination).  In the past I have tried to use DTS to move logins (passwords and SIDs) from one server to another but without much success.  As I was surfing the Internet, I came across 2 stored procedures from Microsoft that you create in the master database.  Once compiled, run the primary stored procedure and the result set produces the CREATE LOGIN statements with the correct passwords and SIDs for every login in the source server.  Once this script has been created, you can then copy it and execute the script in a query window on the destination server.  Once you restore the user databases from the source server to the destination server the SIDs found in the user database will then be sync’d to the logins in the master database. 

You will find both stored procedures below in one script.  The primary stored procedure you execute to generate the CREATE LOGIN script is the stored procedure:  sp_help_revlogin   Here is the correct syntax to run the procedure for ALL logins.  exec sp_help_revlogin

Here is the script with the 2 stored procedures:

USE master
GO

IF OBJECT_ID (‘sp_hexadecimal’) IS NOT NULL
DROP PROCEDURE sp_hexadecimal
GO

CREATE PROCEDURE sp_hexadecimal
@binvalue VARBINARY(256),
@hexvalue VARCHAR(514) OUTPUT

AS

/*
**********************************************************************
**
** Object Name: sp_hexadecimal
** Object Type: Stored Procedure
** File Name: sp_hexadecimal.sql
** Database Name: master
** Author: < Name of the person who wrote the T-SQL
** script >
** Creation Date: 07.10.08 – use ANSI format
** Description: This procedure is involved in scripting out
** logins, passwords and SIDs in SQL Server 2005.
** Special Note: This script is also available from the
** Microsoft website.
** Modified Tables: None
** Called Procedures: None
** Called Jobs: None
** Called UDFs: None
** Calling Procedures: sp_help_revlogin
** Calling Jobs: None
** Calling UDFs: None
** Return Statuses: @hexvalue as OUTPUT
**
**********************************************************************
*/

– Declaration section
DECLARE @charvalue VARCHAR(514)
DECLARE @i INT
DECLARE @length INT
DECLARE @hexstring CHAR(16)

– Initialization section
SELECT @charvalue = ‘0x’
SELECT @i = 1
SELECT @length = DATALENGTH(@binvalue)
SELECT @hexstring = ‘0123456789ABCDEF’

WHILE (@i <= @length)
BEGIN
– Declaration section
DECLARE @tempint INT
DECLARE @firstint INT
DECLARE @secondint INT

– Initialization section
SELECT @tempint = CONVERT(INT, SUBSTRING(@binvalue,@i,1))
SELECT @firstint = FLOOR(@tempint/16)
SELECT @secondint = @tempint – (@firstint*16)
SELECT @charvalue = @charvalue +

SUBSTRING(@hexstring, @firstint+1, 1) + SUBSTRING(@hexstring, @secondint+1, 1)

SELECT @i = @i + 1
END
SELECT @hexvalue = @charvalue
GO

/******************************************************************************/
IF OBJECT_ID (‘sp_help_revlogin’) IS NOT NULL
DROP PROCEDURE sp_help_revlogin
GO

CREATE PROCEDURE sp_help_revlogin
@login_name SYSNAME = NULL

AS

/*
**********************************************************************
**
** Object Name: sp_help_revlogin
** Object Type: Stored Procedure
** File Name: sp_help_revlogin.sql
** Database Name: master
** Author: < Name of the person who wrote the T-SQL
** script >
** Creation Date: 07.10.08 – use ANSI format
** Description: This procedure creates the actual T-SQL ‘Create
** Login’ statement with the information from
** the security tables in SQL Server 2005.
** Special Note: This script is also available from the
** Microsoft website.
** Modified Tables: None
** Called Procedures: sp_hexadecimal
** Called Jobs: None
** Called UDFs: None
** Calling Procedures: None
** Calling Jobs: None
** Calling UDFs: None
** Return Statuses: None
**
**********************************************************************
*/

– Declaration section
DECLARE @name SYSNAME
DECLARE @type VARCHAR(1)
DECLARE @hasaccess INT
DECLARE @denylogin INT
DECLARE @is_disabled INT
DECLARE @PWD_varbinary VARBINARY(256)
DECLARE @PWD_string VARCHAR(514)
DECLARE @SID_varbinary VARBINARY(85)
DECLARE @SID_string VARCHAR(514)
DECLARE @tmpstr VARCHAR(1024)
DECLARE @is_policy_checked VARCHAR(3)
DECLARE @is_expiration_checked VARCHAR(3)

IF @login_name IS NULL
DECLARE login_curs CURSOR FOR
SELECT
p.sid,
p.[name],
p.[type],
p.is_disabled,
l.hasaccess,
l.denylogin
FROM sys.server_principals AS p
LEFT JOIN sys.syslogins AS l
ON l.[name] = p.[name]
WHERE p.[type] IN( ‘S’, ‘G’, ‘U’ )
AND p.[name] <> ‘sa’
ELSE
DECLARE login_curs CURSOR FOR
SELECT p.sid,
p.[name],
p.[type],
p.is_disabled,
l.hasaccess,
l.denylogin
FROM sys.server_principals AS p
LEFT JOIN sys.syslogins AS l
ON l.[name] = p.[name]
WHERE p.[type] IN( ‘S’, ‘G’, ‘U’ )
AND p.[name] = @login_name

OPEN login_curs

FETCH NEXT FROM login_curs
INTO @SID_varbinary, @name, @type, @is_disabled, @hasaccess, @denylogin

IF (@@FETCH_STATUS= -1)
BEGIN
PRINT ‘No login(s) found.’
CLOSE login_curs
DEALLOCATE login_curs
RETURN -1
END

SET @tmpstr = ‘/* sp_help_revlogin script ‘

PRINT @tmpstr

SET @tmpstr = ‘** Generated ‘ + CONVERT (VARCHAR, GETDATE()) + ‘ on ‘ + @@SERVERNAME + ‘ */’

PRINT @tmpstr
PRINT

WHILE ( @@FETCH_STATUS <> -1)
BEGIN
IF (@@FETCH_STATUS <> -2)
BEGIN
PRINT
SET @tmpstr = ‘– Login: ‘ + @name
PRINT @tmpstr

IF (@type IN ( ‘G’, ‘U’))
BEGIN – NT authenticated account/group
SET @tmpstr = ‘CREATE LOGIN ‘ + QUOTENAME( @name ) + ‘FROM WINDOWS’
END
ELSE
BEGIN
– SQL Server authentication
– obtain password and sid
SET @PWD_varbinary = CAST( LOGINPROPERTY( @name, ‘PasswordHash’ ) AS VARBINARY(256))
EXEC sp_hexadecimal @PWD_varbinary, @PWD_string OUT
EXEC sp_hexadecimal @SID_varbinary, @SID_string OUT

– obtain password policy state
SELECT @is_policy_checked =
CASE is_policy_checked WHEN 1 THEN ‘ON’ WHEN 0 THEN ‘OFF’ ELSE NULL END
FROM
sys.sql_logins
WHERE [name] = @name

SELECT @is_expiration_checked =
CASE is_expiration_checked WHEN 1 THEN ‘ON’ WHEN 0 THEN ‘OFF’ ELSE NULL END
FROM
sys.sql_logins
WHERE [name] = @name

SET @tmpstr = ‘CREATE LOGIN ‘ + QUOTENAME( @name )
+ ‘ WITH PASSWORD = ‘ + @PWD_string
+ ‘ HASHED, SID = ‘ + @SID_string

IF ( @is_policy_checked IS NOT NULL )
BEGIN
SET
@tmpstr = @tmpstr + ‘, CHECK_POLICY = ‘ + @is_policy_checked
END

IF ( @is_expiration_checked IS NOT NULL )
BEGIN
SET @tmpstr = @tmpstr + ‘, CHECK_EXPIRATION = ‘ + @is_expiration_checked
END
END

IF (@denylogin = 1)
BEGIN – login is denied access
SET @tmpstr = @tmpstr + ‘; DENY CONNECT SQL TO ‘ + QUOTENAME( @name )
END
ELSE IF
(@hasaccess = 0)
BEGIN – login has exists but does not have access
SET @tmpstr = @tmpstr + ‘; REVOKE CONNECT SQL TO ‘ + QUOTENAME( @name )
END

IF (@is_disabled = 1)
BEGIN — login is disabled
SET @tmpstr = @tmpstr + ‘; ALTER LOGIN ‘ + QUOTENAME( @name ) + ‘ DISABLE’
END

PRINT @tmpstr
END

FETCH NEXT FROM login_curs
INTO @SID_varbinary, @name, @type, @is_disabled, @hasaccess, @denylogin

END

CLOSE login_curs
DEALLOCATE login_curs

RETURN 0
GO