Porting the SQL logins - User Roles

  • Hi,

    I am moving SQL logins from a server instance to another (Both are same versions - SQL server 2008 R2).

    I am using the proposed solution by Miscrosof - http://support.microsoft.com/kb/918992.

    - I run a script that creates two SPs on source server/instance - sp_hexadecimal, sp_help_revlogin.

    - And I run sp_help_revlogin on the source server.

    - Copy the output and run it on the destination server/instance.

    It creates the logins. All good. But I would like to modify this, when it ports the logins and it ports the user mapping as well.

    Here is what I mean - http://screencast.com/t/yH99YEeztoX1.

    The highlighted piece doesn't come over when the login is ported.

    Has anyone able to successfully do it?

    Thank you,

    RM

  • ------------------------------------------------------------------------------------

    -- Description: Provide a list of login(s) and create a script to recreate all login and user settings

    -- Revision History

    -- Date Author Revision Description

    -- 10/19/2005 Terry Duffy Original (Expanded from MS code)

    -- 05/17/06Terry DuffyAdded abliity to limit to a list of databases, changes all char(13) to char(10) for sql05.

    -- 08/02/06Terry DuffyModified for SQL2005

    ------------------------------------------------------------------------------------

    -- Usage

    -- Populate @list variable below with account(s),comma delimited list to script.

    -- Save output to recreate:Login,Default DB,Server Roles,DB Access,DB Roles,DB Object Permissions.

    -- NOTE:

    -- Stored procedures are created in Master, but are deleted

    -- to limit by database see section /*Get a table with dbs where login has access*/ and change the where clause

    -- to script all logins, see section /*To Script all sql and windows logins...

    /*****************************Start Create needed procedures***************************/

    USE master

    GO

    IF OBJECT_ID ('usp_hexadecimal') IS NOT NULL

    DROP PROCEDURE usp_hexadecimal

    GO

    CREATE PROCEDURE usp_hexadecimal

    @binvalue varbinary(256),

    @hexvalue varchar (514) OUTPUT

    AS

    DECLARE @charvalue varchar (514)

    DECLARE @i int

    DECLARE @length int

    DECLARE @hexstring char(16)

    SELECT @charvalue = '0x'

    SELECT @i = 1

    SELECT @length = DATALENGTH (@binvalue)

    SELECT @hexstring = '0123456789ABCDEF'

    WHILE (@i <= @length)

    BEGIN

    DECLARE @tempint int

    DECLARE @firstint int

    DECLARE @secondint int

    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 ('usp_help_revlogin') IS NOT NULL

    DROP PROCEDURE usp_help_revlogin

    GO

    CREATE PROCEDURE usp_help_revlogin @login_name sysname = NULL AS

    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)

    DECLARE @defaultdb sysname

    IF (@login_name IS NULL)

    DECLARE login_curs CURSOR FOR

    SELECT p.sid, p.name, p.type, p.is_disabled, p.default_database_name, l.hasaccess, l.denylogin FROM

    sys.server_principals p LEFT JOIN sys.syslogins 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, p.default_database_name, l.hasaccess, l.denylogin FROM

    sys.server_principals p LEFT JOIN sys.syslogins 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, @defaultdb, @hasaccess, @denylogin

    IF (@@fetch_status = -1)

    BEGIN

    PRINT '--No login(s) found.'

    CLOSE login_curs

    DEALLOCATE login_curs

    RETURN -1

    END

    SET @tmpstr = '/* usp_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 WITH DEFAULT_DATABASE = [' + @defaultdb + ']'

    END

    ELSE BEGIN -- SQL Server authentication

    -- obtain password and sid

    SET @PWD_varbinary = CAST( LOGINPROPERTY( @name, 'PasswordHash' ) AS varbinary (256) )

    EXEC usp_hexadecimal @PWD_varbinary, @PWD_string OUT

    EXEC usp_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 + ', DEFAULT_DATABASE = [' + @defaultdb + ']'

    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 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, @defaultdb, @hasaccess, @denylogin

    END

    CLOSE login_curs

    DEALLOCATE login_curs

    RETURN 0

    GO

    /*****************************End Create needed procedures***************************/

    SET NOCOUNT ON

    Declare

    @List varchar(max),

    @DatabaseUserName sysname,

    @DB_principal_id smallint,

    @ServerUserName sysname,

    @RoleName sysname,

    @DB_Name sysname,

    @CMD varchar(max),

    @default_schema_name sysname,

    @DB_Nam sysname,

    @state_desc sysname,

    @permission_name sysname ,

    @schema_name sysname ,

    @object_name sysname ,

    @user_name sysname

    /******************************************USER LIST HERE******************************/

    /*E.G. 'User1, user3,domain\user1,domain\user2'*/

    set @List = 'sqladmin'

    /*To Script all sql and windows logins uncomment below, note this may re-create undesired accounts and

    should be modified in the where clause when needed*/

    --select @list = isnull(@list,'') + [name] + ',' from master.sys.server_principals where type in ('S','U','G')

    if right(@List,1) <> ','

    Begin

    set @List = @List + ','

    End

    Create Table ##DB_USERs

    (

    name sysname,

    DatabaseUserID smallint null,

    ServerUserName sysname null,

    default_schema_name sysname null

    )

    Create Table ##DB_Roles

    (

    Name sysname

    )

    CREATE TABLE ##syspermissions (

    [DB_Name] [sysname] NULL ,

    [state_desc] [sysname] NULL ,

    [permission_name] [sysname] NULL ,

    [schema_name] [sysname] NULL ,

    [object_name] [sysname] NULL ,

    [user_name] [sysname] NULL,

    [principal_id] [int] NULL

    )

    CREATE TABLE ##SRV_Roles

    (

    SERVERROLE VARCHAR(100),

    MEMBERNAME VARCHAR(100),

    MEMBERSID VARBINARY (85)

    )

    /*Loop thru file_list*/

    while @List <> ''

    Begin

    set @DatabaseUserName = left( @List, charindex( ',', @List ) - 1 )

    Print '--BEGIN ' + @DatabaseUserName + ' ************************************'

    Print '--********Begin Script the Login ********************************************************'

    /*Script login with password*/

    Execute usp_help_revlogin @DatabaseUserName

    Print 'GO'

    /*GET SERVER ROLES INTO TEMPORARY TABLE*/

    SET @CMD = '[master].[dbo].[sp_helpsrvrolemember]'

    INSERT INTO ##SRV_Roles EXEC (@CMD)

    Set @CMD = ''

    Select @CMD = @CMD + 'EXEC sp_addsrvrolemember @loginame = ' + char(39) + MEMBERNAME + char(39) + ', @rolename = ' + char(39) + SERVERROLE + char(39) + char(10) + 'GO' + char(10)

    from ##SRV_Roles where MEMBERNAME = @DatabaseUserName

    Print '--Assign Server Roles'

    Print @CMD

    Delete ##SRV_Roles

    Print '--********End Script the Login *********************************************************'

    Print ''

    /*Get a table with dbs where login has access*/

    set @DB_Name = ''

    While @DB_Name is not null

    Begin

    Select

    @DB_Name = min(name)

    from

    master.sys.databases

    where

    /*limit by database if needed*/

    name > @DB_Name

    --and name in ('Accounting','CAMDW_DST','Employee','FFS_Staging','HRTraining')

    IF @DB_Name IS NULL BREAK

    Set @CMD =

    'insert ##DB_USERs

    SELECT '

    + char(39) + @DB_Name + char(39) + ',' +

    'u.[principal_id],

    l.[name],

    u.default_schema_name

    FROM '

    + '[' + @DB_Name + '].[sys].[database_principals] u

    INNER JOIN [master].[sys].[server_principals] l

    ON u.[sid] = l.[sid]

    WHERE

    u.[name] = ' + char(39) + @DatabaseUserName + char(39)

    Exec (@CMD)

    End

    /*Add users/roles/object permissions to databases*/

    set @DB_Name = ''

    While @DB_Name is not null

    Begin

    Select

    @DB_Name = min(name)

    from

    ##DB_USERs

    where

    name > @DB_Name

    if @DB_Name is null BREAK

    Print '/************Begin Database ' + @DB_Name + ' ****************/'

    select @ServerUserName = ServerUserName,@DB_principal_id = DatabaseUserID,@default_schema_name = default_schema_name from ##DB_USERs where name = @DB_Name

    Set @CMD =

    'USE [' + @DB_Name + '];' + char(10) +

    'CREATE USER [' + @DatabaseUserName + ']' + char(10) +

    CHAR(9) + 'FOR LOGIN [' + @ServerUserName + ']' + char(10) +

    CHAR(9) + 'With DEFAULT_SCHEMA = [' + @default_schema_name + ']' + char(10) +

    'GO'

    Print '--Add user to databases'

    Print @CMD

    /*Populate roles for this user*/

    Select @CMD =

    'Insert ##DB_Roles

    Select name

    FROM '

    + '[' + @DB_Name + '].[sys].[database_principals]

    WHERE

    [principal_id] IN (SELECT [role_principal_id] FROM [' + @DB_Name + '].[sys].[database_role_members] WHERE [member_principal_id] = ' + cast(@DB_principal_id as varchar(25)) + ')'

    --Print @CMD

    Exec (@CMD)

    /*Add user to roles*/

    Set @CMD = ''

    Select @CMD = isnull(@CMD,'') + 'EXEC [sp_addrolemember]' + char(10) +

    CHAR(9) + '@rolename = ''' + Name + ''',' + char(10) +

    CHAR(9) + '@MemberName = ''' + @DatabaseUserName + ''''+ char(10) +

    'GO' + char(10)

    from ##DB_Roles

    if len(@CMD) > 0

    Print '--Add user to role(s)'

    Print @CMD

    Delete ##DB_Roles

    /*Object Permissions*/

    Set @CMD =

    '

    Insert ##syspermissions

    select ' + char(39) + @DB_Name + char(39) + ',a.[state_desc],a.[permission_name], d.[name],b.[name],c.[name],c.[principal_id]

    from '

    + '[' + @DB_Name + '].sys.database_permissions a

    JOIN ' + '[' + @DB_Name + '].[sys].[objects] b

    ON a.major_id = b.object_id

    JOIN ' + '[' + @DB_Name + '].[sys].[database_principals] c

    ON grantee_principal_id = c.principal_id

    JOIN '+ '[' + @DB_Name + '].sys.schemas d

    ON b.schema_id = d.schema_id'

    Exec (@CMD)

    If exists (select 1 from ##syspermissions where principal_id = @DB_principal_id)

    Print '--Assign specific object permissions'

    DECLARE crs_Permissions CURSOR LOCAL FORWARD_ONLY READ_ONLY

    FOR

    SELECT

    [DB_Name],

    [state_desc],

    [permission_name] ,

    [schema_name] ,

    [object_name] ,

    [user_name]

    FROM

    ##syspermissions

    Where

    principal_id = @DB_principal_id

    OPEN crs_Permissions

    FETCH NEXT FROM crs_Permissions INTO @DB_Name,@state_desc,@permission_name ,@schema_name ,@object_name ,@user_name

    WHILE @@FETCH_STATUS = 0

    BEGIN

    SET @CMD = @state_desc + ' ' + @permission_name + ' ON [' + @schema_name + '].[' + @object_name + '] TO [' + @user_name + ']'

    Print @CMD

    FETCH NEXT FROM crs_Permissions INTO @DB_Name,@state_desc,@permission_name ,@schema_name ,@object_name ,@user_name

    END

    CLOSE crs_Permissions

    DEALLOCATE crs_Permissions

    delete ##syspermissions

    Print '/************End Database ' + @DB_Name + ' ****************/'

    Print ''

    /*next db*/

    End

    Print '--END ' + @DatabaseUserName + ' ************************************'

    Print ''

    /*Parse the list down*/

    set @List = right( @List, datalength( @List ) - charindex( ',', @List ) )

    /*Clear data for the last user*/

    Delete ##DB_USERs

    End

    /*Clean up*/

    Drop table ##DB_USERs

    Drop table ##DB_Roles

    drop table ##syspermissions

    Drop table ##SRV_Roles

    use master

    Drop procedure usp_help_revlogin

    Drop procedure usp_hexadecimal

Viewing 3 posts - 1 through 2 (of 2 total)

You must be logged in to reply to this topic. Login to reply