programing

SQL Server 사용 권한 스크립팅

bestprogram 2023. 6. 21. 22:50

SQL Server 사용 권한 스크립팅

저장 프로시저 및 기타 항목에 대해 설정한 모든 권한을 개발 데이터베이스에서 프로덕션 데이터베이스로 복사하려고 합니다.SSMS GUI 도구를 통해 이 모든 작업을 수작업으로 수행하는 것은 오류가 발생하기 쉬운 것은 말할 것도 없고 매우 번거롭습니다.

따라서 한 데이터베이스에 설정된 권한을 직접 덤프하고 동일한 권한을 별도의 데이터베이스(아마도 동일한 스키마)에 적용할 수 있는 방법을 찾고 있습니다.

데이터베이스의 기본 제공 카탈로그 보기는 이를 위한 정보를 제공합니다.다음 쿼리를 시도해 보십시오.

SELECT
  (
    dp.state_desc + ' ' +
    dp.permission_name collate latin1_general_cs_as + 
    ' ON ' + '[' + s.name + ']' + '.' + '[' + o.name + ']' +
    ' TO ' + '[' + dpr.name + ']'
  ) AS GRANT_STMT
FROM sys.database_permissions AS dp
  INNER JOIN sys.objects AS o ON dp.major_id=o.object_id
  INNER JOIN sys.schemas AS s ON o.schema_id = s.schema_id
  INNER JOIN sys.database_principals AS dpr ON dp.grantee_principal_id=dpr.principal_id
WHERE dpr.name NOT IN ('public','guest')
--  AND o.name IN ('My_Procedure')      -- Uncomment to filter to specific object(s)
--  AND dp.permission_name='EXECUTE'    -- Uncomment to filter to just the EXECUTEs

그러면 데이터베이스의 각 권한에 대한 명령 모음(GRANT/DENY)이 뱉어집니다.이를 통해 복사하여 다른 쿼리 창에 붙여넣고 실행하여 원본과 동일한 권한을 생성할 수 있습니다.예:

GRANT EXECUTE ON [Exposed].[EmployeePunchoutReservationRetrieve] TO [CustomerAgentRole]
GRANT EXECUTE ON [Exposed].[EmployeePunchoutReservationStore] TO [CustomerAgentRole]
GRANT EXECUTE ON [Exposed].[EmployeePunchoutSendOrderLogStore] TO [CustomerAgentRole]
GRANT EXECUTE ON [Exposed].[EmployeeReportSubscriptions] TO [CustomerAgentRole]

마지막으로, permission_name에 대한 필터링을 언급했습니다.해당 줄에 주석을 달지 않으면 쿼리가 EXECUTE 권한(즉, 저장 프로시저에 대한 권한)만 뱉게 됩니다.

SQL Server Management Studio에서 다음 작업을 수행할 수 있습니다.

  • 권한을 내보낼 데이터베이스를 마우스 오른쪽 단추로 클릭합니다.
  • '작업'을 선택한 다음 '스크립트 생성....'
  • 스크립팅 중인 데이터베이스 확인
  • 다음 스크립팅 옵션을 설정합니다.
    • 스크립트 생성: FALSE
    • 스크립트 개체 수준 사용 권한: TRUE
  • 스크립팅할 권한이 있는 개체 유형 선택
  • 스크립팅할 권한이 있는 개체 선택
  • 스크립트를 생성할 위치 선택

이렇게 하면 선택한 모든 개체에 대한 사용 권한을 설정하는 스크립트가 생성되지만 개체 스크립트 자체는 억제됩니다.

이는 설치 기본값에서 변경되지 않은 다른 모든 스크립팅 옵션이 있는 MS SQL 2008 대화 상자를 기반으로 합니다.

데이터베이스/스키마 전체 권한 및 데이터베이스 사용자 유형에 대해 실패한 답변을 확장하여 다음을 사용할 수 있습니다.

SELECT
  CASE
      WHEN dp.class_desc = 'OBJECT_OR_COLUMN' THEN
        dp.state_desc + ' ' + dp.permission_name collate latin1_general_cs_as + 
        ' ON ' + '[' + obj_sch.name + ']' + '.' + '[' + o.name + ']' +
        ' TO ' + '[' + dpr.name + ']'
      WHEN dp.class_desc = 'DATABASE' THEN
        dp.state_desc + ' ' + dp.permission_name collate latin1_general_cs_as + 
        ' TO ' + '[' + dpr.name + ']'
      WHEN dp.class_desc = 'SCHEMA' THEN
        dp.state_desc + ' ' + dp.permission_name collate latin1_general_cs_as + 
        ' ON SCHEMA :: ' + '[' + SCHEMA_NAME(dp.major_id) + ']' +
        ' TO ' + '[' + dpr.name + ']'
      WHEN dp.class_desc = 'TYPE' THEN
        dp.state_desc + ' ' + dp.permission_name collate Latin1_General_CS_AS + 
        ' ON TYPE :: [' + s_types.name + '].[' + t.name + ']'
            + ' TO [' + dpr.name + ']'
      WHEN dp.class_desc = 'CERTIFICATE' THEN 
        dp.state_desc + ' ' + dp.permission_name collate latin1_general_cs_as + 
        ' TO ' + '[' + dpr.name + ']' 
      WHEN dp.class_desc = 'SYMMETRIC_KEYS' THEN 
        dp.state_desc + ' ' + dp.permission_name collate latin1_general_cs_as + 
      ' TO ' + '[' + dpr.name + ']' 
      ELSE 
        'ERROR: Unhandled class_desc: ' + dp.class_desc
  END
 AS GRANT_STMT
FROM sys.database_permissions AS dp 
  JOIN sys.database_principals AS dpr ON dp.grantee_principal_id=dpr.principal_id
  LEFT JOIN sys.objects AS o ON dp.major_id=o.object_id
  LEFT JOIN sys.schemas AS obj_sch ON o.schema_id = obj_sch.schema_id
  LEFT JOIN sys.types AS t ON dp.major_id = t.user_type_id
  LEFT JOIN sys.schemas AS s_types ON t.schema_id = s_types.schema_id
WHERE 
dpr.name NOT IN ('public','guest') 
--  AND o.name IN ('My_Procedure')      -- Uncomment to filter to specific object(s)
--  AND (o.name NOT IN ('My_Procedure') or o.name is null)  -- Uncomment to filter out specific object(s), but include rows with no o.name (VIEW DEFINITION etc.)
--  AND dp.permission_name='EXECUTE'    -- Uncomment to filter to just the EXECUTEs
--  AND dpr.name LIKE '%user_name%'     -- Uncomment to filter to just matching users
ORDER BY dpr.name, dp.class_desc, dp.permission_name

예, 이와 같은 스크립트를 사용하여 다른 스크립트를 생성할 수 있습니다.

SET NOCOUNT ON;
DECLARE @NewRole varchar(100), @SourceRole varchar(100);

-- Change as needed
SELECT @SourceRole = 'Giver', @NewRole = 'Taker';

SELECT
    state_desc + ' ' + permission_name + ' ON ' + OBJECT_NAME(major_id) + ' TO ' + @NewRole
FROM
    sys.database_permissions
WHERE
    grantee_principal_id = DATABASE_PRINCIPAL_ID(@SourceRole) AND
    -- 0 = DB,  1 = object/column, 3 = schema. 1 is normally enough
    class <= 3

이것은 여기 제 대답에서 발췌한 것입니다.

SELECT
    dp.state_desc + ' ' 
       + dp.permission_name collate latin1_general_cs_as
       + ISNULL((' ON ' + QUOTENAME(s.name) + '.' + QUOTENAME(o.name)),'')
       + ' TO ' + QUOTENAME(dpr.name)
FROM sys.database_permissions AS dp
  LEFT JOIN sys.objects AS o ON dp.major_id=o.object_id
  LEFT JOIN sys.schemas AS s ON o.schema_id = s.schema_id
  LEFT JOIN sys.database_principals AS dpr ON dp.grantee_principal_id=dpr.principal_id
WHERE dpr.name NOT IN ('public','guest')

개체 수준 외에 데이터베이스 수준에서 적용되는 사용 권한을 가져오려는 경우 허용된 응답이 약간 변경됩니다.기본적으로 다음으로 전환LEFT JOIN그리고 반드시 처리해야 합니다.NULL위해서object그리고.schema names.

아래 링크에서 코드를 다운로드하여 작동 방식을 확인할 수도 있습니다.

https://gallery.technet.microsoft.com/Extract-Database-dfa53d5a

이렇게 하면 이 쿼리의 출력을 볼 수 있습니다.

set nocount off

IF OBJECT_ID(N'tempdb..##temp1') IS NOT NULL
     DROP TABLE ##temp1

create table ##temp1(query varchar(1000))

insert into ##temp1 
select 'use '+db_name() +';'

insert into ##temp1 
select 'go'

/*creating database roles*/
insert into ##temp1
                    select 'if DATABASE_PRINCIPAL_ID('''+name+''')  is null 
                    exec sp_addrole '''+name+''''  from sysusers
where issqlrole = 1 and (sid is not null and sid <> 0x0)

/*creating application roles*/
insert into ##temp1
                    select 'if DATABASE_PRINCIPAL_ID('+char(39)+name+char(39)+')
                    is null CREATE APPLICATION ROLE ['+name+'] WITH DEFAULT_SCHEMA = ['+
                    default_schema_name+'], Password='+char(39)+'Pass$w0rd123'+char(39)+' ;'
 from sys.database_principals
where type_desc='APPLICATION_ROLE'

insert into ##temp1 
                     select  
                                case  
                                          when state_desc='GRANT_WITH_GRANT_OPTION' 
                                                       then
                                                                substring (state_desc,0,6)+' '+permission_name+' to '+'['+USER_NAME(grantee_principal_id)+']'+' WITH GRANT OPTION ;'

                                                         else 
                                                                  state_desc+' '+permission_name+' to '+'['+USER_NAME(grantee_principal_id)+']'+' ;'
                    END
from sys.database_permissions 
where class=0 and USER_NAME(grantee_principal_id) not in ('dbo','guest','sys','information_schema')

insert into ##temp1 
                    select 
                               case 
                                         when state_desc='GRANT_WITH_GRANT_OPTION' 
                                                   then
                                                             substring (state_desc,0,6)+' '+permission_name+' on '+OBJECT_SCHEMA_NAME(major_id)+'.['+OBJECT_NAME(major_id)
                                                             +'] to '+'['+USER_NAME(grantee_principal_id)+']'+' with grant option ;'
                                                     else 
                                                              state_desc+' '+permission_name+' on '+OBJECT_SCHEMA_NAME(major_id)+'.['+OBJECT_NAME(major_id)
                                                              +'] to '+'['+USER_NAME(grantee_principal_id)+']'+' ;'
                                  end
from sys.database_permissions where class=1 and USER_NAME(grantee_principal_id) not in ('public');


 insert into ##temp1 
                      select 
                                 case 
                                           when state_desc='GRANT_WITH_GRANT_OPTION' 
                                                     then
                                                              substring (state_desc,0,6)+' '+permission_name+' ON schema::['+sa.name+
                                                               '] to ['+user_name(dp.grantee_principal_id)+'] with grant option ;'
                                                       else
                                                               state_desc+' '+permission_name+' ON schema::['+sa.name+
                                                               '] to ['+user_name(dp.grantee_principal_id)+'] ;'
                                                       COLLATE LATIN1_General_CI_AS  
                                      end
from sys.database_permissions dp inner join sys.schemas sa on
 sa.schema_id = dp.major_id where dp.class=3

 insert into ##temp1 
                     select 
                                 case 
                                            when state_desc='GRANT_WITH_GRANT_OPTION'
                                             then
                                                    substring (state_desc,0,6)+' '+permission_name+' ON APPLICATION  ROLE::['+sa.name+
                                                     '] to ['+user_name(dp.grantee_principal_id)+'] with grant option ;'
                                             else
                                                      state_desc+' '+permission_name+' ON  APPLICATION ROLE::['+sa.name+
                                                      '] to ['+user_name(dp.grantee_principal_id)+'] ;'
                                                      COLLATE LATIN1_General_CI_AS  
                         end
from sys.database_permissions dp inner join sys.database_principals  sa on
 sa.principal_id = dp.major_id where dp.class=4 and sa.type='A'

 insert into ##temp1 
                      select 
                                 case 
                                          when state_desc='GRANT_WITH_GRANT_OPTION' 
                                           then
                                                  substring (state_desc,0,6)+' '+permission_name+' ON   ROLE::['+sa.name+
                                                  '] to ['+user_name(dp.grantee_principal_id)+'] with grant option ;'
                                           else
                                                   state_desc+' '+permission_name+' ON   ROLE::['+sa.name+
                                                    '] to ['+user_name(dp.grantee_principal_id)+'] ;'
                                                     COLLATE LATIN1_General_CI_AS  
                                           end
 from sys.database_permissions dp inner join
sys.database_principals  sa on sa.principal_id = dp.major_id 
 where dp.class=4 and sa.type='R'

 insert into ##temp1 
                      select 
                                  case 
                                           when state_desc='GRANT_WITH_GRANT_OPTION' 
                                                       then
                                                               substring (state_desc,0,6)+' '+permission_name+' ON ASSEMBLY::['+sa.name+
                                                                '] to ['+user_name(dp.grantee_principal_id)+'] with grant option ;'
                                                        else
                                                                state_desc+' '+permission_name+' ON ASSEMBLY::['+sa.name+
                                                                 '] to ['+user_name(dp.grantee_principal_id)+'] ;'
                                                                 COLLATE LATIN1_General_CI_AS  
                                       end
 from sys.database_permissions dp inner join sys.assemblies sa on
 sa.assembly_id = dp.major_id 
 where dp.class=5

 insert into ##temp1
                     select 
                                 case 
                                           when state_desc='GRANT_WITH_GRANT_OPTION' 
                                            then
                                                    substring (state_desc,0,6)+'  '+permission_name+' ON type::['
                                                    +SCHEMA_NAME(schema_id)+'].['+sa.name+
                                                    '] to ['+user_name(dp.grantee_principal_id)+'] with grant option ;'
                                            else
                                                    state_desc+' '+permission_name+' ON type::['
                                                    +SCHEMA_NAME(schema_id)+'].['+sa.name+
                                                     '] to ['+user_name(dp.grantee_principal_id)+'] ;'
                                                     COLLATE LATIN1_General_CI_AS  
                                              end
 from sys.database_permissions dp inner join sys.types sa on
 sa.user_type_id = dp.major_id 
 where dp.class=6


 insert into ##temp1
                      select 
                                 case 
                                          when state_desc='GRANT_WITH_GRANT_OPTION' 
                                           then
                                                     substring (state_desc,0,6)+'  '+permission_name+' ON  XML SCHEMA COLLECTION::['+
                                                     SCHEMA_NAME(SCHEMA_ID)+'].['+sa.name+'] to ['+user_name(dp.grantee_principal_id)+'] with grant option ;'
                                            else
                                                     state_desc+' '+permission_name+' ON  XML SCHEMA COLLECTION::['+
                                                     SCHEMA_NAME(SCHEMA_ID)+'].['+sa.name+'] to ['+user_name(dp.grantee_principal_id)+'];'
                                                     COLLATE LATIN1_General_CI_AS  
                                   end
 from sys.database_permissions dp inner join sys.xml_schema_collections sa on
 sa.xml_collection_id = dp.major_id 
 where dp.class=10



insert into ##temp1
                    select
                               case 
                                         when state_desc='GRANT_WITH_GRANT_OPTION' 
                                          then
                                                   substring (state_desc,0,6)+'  '+permission_name+' ON message type::['+sa.name+
                                                    '] to ['+user_name(dp.grantee_principal_id)+'] with grant option ;'
                                           else
                                                    state_desc+' '+permission_name+' ON message type::['+sa.name+
                                                    '] to ['+user_name(dp.grantee_principal_id)+'] ;'
                                                     COLLATE LATIN1_General_CI_AS  
                                             end
 from sys.database_permissions dp inner join sys.service_message_types sa on
 sa.message_type_id = dp.major_id 
 where dp.class=15


 insert into ##temp1
                      select 
                                  case 
                                            when state_desc='GRANT_WITH_GRANT_OPTION' 
                                              then
                                                       substring (state_desc,0,6)+'  '+permission_name+' ON contract::['+sa.name+
                                                        '] to ['+user_name(dp.grantee_principal_id)+'] with grant option ;'
                                                else
                                                         state_desc+' '+permission_name+' ON contract::['+sa.name+
                                                         '] to ['+user_name(dp.grantee_principal_id)+'] ;'
                                                         COLLATE LATIN1_General_CI_AS  
                                   end
 from sys.database_permissions dp inner join sys.service_contracts sa on
 sa.service_contract_id = dp.major_id 
 where dp.class=16



  insert into ##temp1
                      select 
                                 case 
                                           when state_desc='GRANT_WITH_GRANT_OPTION' 
                                            then
                                                      substring (state_desc,0,6)+'  '+permission_name+' ON SERVICE::['+sa.name+
                                                        '] to ['+user_name(dp.grantee_principal_id)+'] with grant option ;'
                                              else
                                                       state_desc+'  '+permission_name+' ON SERVICE::['+sa.name+
                                                        '] to ['+user_name(dp.grantee_principal_id)+'] ;'
                                                        COLLATE LATIN1_General_CI_AS  
                                    end
 from sys.database_permissions dp inner join sys.services sa on
 sa.service_id = dp.major_id 
 where dp.class=17


 insert into ##temp1 
                      select 
                                   case 
                                              when state_desc='GRANT_WITH_GRANT_OPTION'
                                               then
                                                          substring (state_desc,0,6)+'  '+permission_name+' ON REMOTE SERVICE BINDING::['+sa.name+
                                                          '] to ['+user_name(dp.grantee_principal_id)+'] with grant option ;'
                                                 else
                                                          state_desc+' '+permission_name+' ON REMOTE SERVICE BINDING::['+sa.name+
                                                           '] to ['+user_name(dp.grantee_principal_id)+'] ;'
                                                          COLLATE LATIN1_General_CI_AS  
                                      end
 from sys.database_permissions dp inner join sys.remote_service_bindings sa on
 sa.remote_service_binding_id = dp.major_id 
 where dp.class=18

 insert into ##temp1
                      select
                                  case 
                                            when state_desc='GRANT_WITH_GRANT_OPTION'
                                              then
                                                        substring (state_desc,0,6)+'  '+permission_name+' ON route::['+sa.name+
                                                        '] to ['+user_name(dp.grantee_principal_id)+'] with grant option ;'
                                                else
                                                          state_desc+' '+permission_name+' ON route::['+sa.name+
                                                          '] to ['+user_name(dp.grantee_principal_id)+'] ;'
                                                         COLLATE LATIN1_General_CI_AS  
                                      end
 from sys.database_permissions dp inner join sys.routes sa on
 sa.route_id = dp.major_id 
 where dp.class=19

 insert into ##temp1 
                      select 
                                 case 
                                           when state_desc='GRANT_WITH_GRANT_OPTION' 
                                            then
                                                     substring (state_desc,0,6)+'  '+permission_name+' ON FULLTEXT CATALOG::['+sa.name+
                                                      '] to ['+user_name(dp.grantee_principal_id)+'] with grant option ;'
                                             else
                                                       state_desc+' '+permission_name+' ON FULLTEXT CATALOG::['+sa.name+
                                                       '] to ['+user_name(dp.grantee_principal_id)+'] ;'
                                                        COLLATE LATIN1_General_CI_AS  
                                       end
 from sys.database_permissions dp inner join sys.fulltext_catalogs sa on
 sa.fulltext_catalog_id = dp.major_id 
 where dp.class=23

  insert into ##temp1 
                      select 
                                 case 
                                           when state_desc='GRANT_WITH_GRANT_OPTION'
                                            then
                                                        substring (state_desc,0,6)+'  '+permission_name+' ON SYMMETRIC KEY::['+sa.name+
                                                        '] to ['+user_name(dp.grantee_principal_id)+'] with grant option ;'
                                             else
                                                        state_desc+' '+permission_name+' ON SYMMETRIC KEY::['+sa.name+
                                                        '] to ['+user_name(dp.grantee_principal_id)+'] ;'
                                                        COLLATE LATIN1_General_CI_AS  
                                             end
 from sys.database_permissions dp inner join sys.symmetric_keys sa on
 sa.symmetric_key_id = dp.major_id 
 where dp.class=24

 insert into ##temp1 
                      select 
                                  case 
                                           when state_desc='GRANT_WITH_GRANT_OPTION' 
                                             then
                                                       substring (state_desc,0,6)+'  '+permission_name+' ON certificate::['+sa.name+
                                                        '] to ['+user_name(dp.grantee_principal_id)+'] with grant option ;'
                                               else
                                                          state_desc+' '+permission_name+' ON certificate::['+sa.name+
                                                          '] to ['+user_name(dp.grantee_principal_id)+'] ;'
                                                           COLLATE LATIN1_General_CI_AS  
                                   end
 from sys.database_permissions dp inner join sys.certificates sa on
 sa.certificate_id = dp.major_id 
 where dp.class=25


 insert into ##temp1 
                     select 
                                 case 
                                          when state_desc='GRANT_WITH_GRANT_OPTION' 
                                          then
                                                     substring (state_desc,0,6)+'  '+permission_name+' ON ASYMMETRIC KEY::['+sa.name+
                                                     '] to ['+user_name(dp.grantee_principal_id)+'] with grant option ;'
                                             else
                                                      state_desc+' '+permission_name+' ON ASYMMETRIC KEY::['+sa.name+
                                                       '] to ['+user_name(dp.grantee_principal_id)+'] ;'
                                                       COLLATE LATIN1_General_CI_AS  
                        end
 from sys.database_permissions dp inner join sys.asymmetric_keys sa on
 sa.asymmetric_key_id = dp.major_id 
 where dp.class=26

insert into ##temp1 
                     select  'exec sp_addrolemember ''' +p.NAME+''','+'['+m.NAME+']'+' ;'
FROM sys.database_role_members rm
JOIN sys.database_principals p
ON rm.role_principal_id = p.principal_id
JOIN sys.database_principals m
ON rm.member_principal_id = m.principal_id
where m.name not like 'dbo';






select *  from ##temp1  

Chris의 멋진 답변 덕분에, 저는 한 걸음 더 나아가 이러한 진술을 실행하는 프로세스를 자동화했습니다(제 테이블에는 8,000개 이상의 권한이 있습니다).

if object_id('dbo.tempPermissions') is not null
Drop table dbo.tempPermissions

Create table tempPermissions(ID int identity , Queries Varchar(255))


Insert into tempPermissions(Queries)


select 'GRANT ' + dp.permission_name collate latin1_general_cs_as
   + ' ON ' + s.name + '.' + o.name + ' TO ' + dpr.name 
   FROM sys.database_permissions AS dp
   INNER JOIN sys.objects AS o ON dp.major_id=o.object_id
   INNER JOIN sys.schemas AS s ON o.schema_id = s.schema_id
   INNER JOIN sys.database_principals AS dpr ON dp.grantee_principal_id=dpr.principal_id
   WHERE dpr.name NOT IN ('public','guest')

declare @count int, @max int, @query Varchar(255)
set @count =1
set @max = (Select max(ID) from tempPermissions)
set @query = (Select Queries from tempPermissions where ID = @count)

while(@count < @max)
begin
exec(@query)
set @count += 1
set @query = (Select Queries from tempPermissions where ID = @count)
end

select * from tempPermissions

drop table tempPermissions

추가로 단일 테이블로 제한하려면 다음을 추가합니다.

  and o.name = 'tablename'

WHERE dpr.name NOT IN('public', 'public') 후에 권한을 부여할 테이블에 대한 문을 생성하도록 select 문을 편집해야 합니다.'To' 테이블이 아니라 권한이 'FROM'(스크립트가 수행하는 작업)으로 옵니다.

저희 버전:

SET NOCOUNT ON

DECLARE @message NVARCHAR(MAX)

-- GENERATE LOGINS CREATE SCRIPT


USE [master]

-- creating accessory procedure

IF EXISTS (SELECT 1 FROM    sys.objects WHERE   object_id = OBJECT_ID(N'sp_hexadecimal') AND type IN ( N'P', N'PC' )) 
DROP PROCEDURE [dbo].[sp_hexadecimal]
EXEC('
CREATE PROCEDURE [dbo].[sp_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')

SET @message = '-- CREATE LOGINS' + CHAR(13) + CHAR(13) +'USE [master]' + CHAR(13)

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  NVARCHAR(MAX)
DECLARE @is_policy_checked varchar (3)
DECLARE @is_expiration_checked varchar (3)

DECLARE @defaultdb sysname

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'

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
END

WHILE (@@fetch_status <> -1)
BEGIN
  IF (@@fetch_status <> -2)
  BEGIN

    IF (@type IN ( 'G', 'U'))
    BEGIN -- NT authenticated account/group

      SET @tmpstr = 'IF NOT EXISTS (SELECT loginname FROM master.dbo.syslogins WHERE name = ''' + @name + ''' AND dbname = ''' + @defaultdb + ''')' + CHAR(13) +
                    'BEGIN TRY' + CHAR(13) +
                    '   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 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 = 'IF NOT EXISTS (SELECT loginname FROM master.dbo.syslogins WHERE name = ''' + @name + ''' AND dbname = ''' + @defaultdb + ''')' + CHAR(13) +
                    'BEGIN TRY' + CHAR(13) +
                    '   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

    SET @tmpstr = @tmpstr + CHAR(13) + 'END TRY' + CHAR(13) + 'BEGIN CATCH' + CHAR(13) + 'END CATCH'

    SET @message = @message + CHAR(13) + @tmpstr

  END

  FETCH NEXT FROM login_curs INTO @SID_varbinary, @name, @type, @is_disabled, @defaultdb, @hasaccess, @denylogin
   END
CLOSE login_curs
DEALLOCATE login_curs

--removing accessory procedure

DROP PROCEDURE [dbo].[sp_hexadecimal]


-- GENERATE SERVER PERMISSIONS
USE [master]

DECLARE @ServerPrincipal SYSNAME
DECLARE @PrincipalType SYSNAME 
DECLARE @PermissionName SYSNAME
DECLARE @StateDesc SYSNAME

SET @message = @message + CHAR(13) + CHAR(13) + '-- CREATE SERVER PERMISSIONS' + CHAR(13) + CHAR(13) +'USE [master]' + CHAR(13)

DECLARE server_permissions_curs CURSOR FOR
SELECT
  [srvprin].[name] [server_principal], 
  [srvprin].[type_desc] [principal_type], 
  [srvperm].[permission_name], 
  [srvperm].[state_desc]  
FROM [sys].[server_permissions] srvperm 
  INNER JOIN [sys].[server_principals] srvprin 
    ON [srvperm].[grantee_principal_id] = [srvprin].[principal_id] 
WHERE [srvprin].[type] IN ('S', 'U', 'G') AND [srvprin].name NOT IN ('sa', 'dbo', 'information_schema', 'sys')
ORDER BY [server_principal], [permission_name]; 

OPEN server_permissions_curs

FETCH NEXT FROM server_permissions_curs INTO @ServerPrincipal, @PrincipalType, @PermissionName, @StateDesc 

WHILE (@@fetch_status <> -1)
BEGIN

    SET @message = @message + CHAR(13) + 'BEGIN TRY' + CHAR(13) + 
                    @StateDesc + N' ' + @PermissionName + N' TO ' + QUOTENAME(@ServerPrincipal) + 
                    + CHAR(13) + 'END TRY' + CHAR(13) + 'BEGIN CATCH' + CHAR(13) + 'END CATCH'

    FETCH NEXT FROM server_permissions_curs INTO @ServerPrincipal, @PrincipalType, @PermissionName, @StateDesc 
END
CLOSE server_permissions_curs
DEALLOCATE server_permissions_curs

--GENERATE USERS AND PERMISSION SCRIPT FOR EVERY DATABASE

SET @message = @message + CHAR(13) + CHAR(13) + N'--ENUMERATE DATABASES'

DECLARE @databases TABLE (
    DatabaseName SYSNAME,
    DatabaseSize INT,
    Remarks SYSNAME NULL
)

INSERT INTO
@databases EXEC sp_databases

DECLARE @DatabaseName SYSNAME


DECLARE database_curs CURSOR FOR
SELECT DatabaseName FROM @databases WHERE DatabaseName IN (N'${DatabaseName}')

OPEN database_curs

FETCH NEXT FROM database_curs INTO @DatabaseName
WHILE (@@fetch_status <> -1)
BEGIN

    SET @tmpStr = 

    N'USE ' + QUOTENAME(@DatabaseName) + '

    DECLARE @tmpstr  NVARCHAR(MAX)

    SET @messageOut = CHAR(13) + CHAR(13) + ''USE ' + QUOTENAME(@DatabaseName) + ''' + CHAR(13)

    -- GENERATE USERS SCRIPT 

    SET @messageOut = @messageOut + CHAR(13) + ''-- CREATE USERS '' + CHAR(13)

    DECLARE @users TABLE (
    UserName SYSNAME Null,  
    RoleName SYSNAME Null,  
    LoginName SYSNAME Null, 
    DefDBName SYSNAME Null, 
    DefSchemaName SYSNAME Null, 
    UserID INT Null,    
    [SID] varbinary(85) Null
    )

    INSERT INTO
    @users   EXEC sp_helpuser

    DECLARE @UserName SYSNAME
    DECLARE @LoginName SYSNAME 
    DECLARE @DefSchemaName SYSNAME

    DECLARE user_curs CURSOR FOR
    SELECT UserName, LoginName, DefSchemaName FROM @users

    OPEN user_curs

    FETCH NEXT FROM user_curs INTO @UserName, @LoginName, @DefSchemaName
    WHILE (@@fetch_status <> -1)
    BEGIN

        SET @messageOut = @messageOut + CHAR(13) + 
                        ''IF NOT EXISTS (SELECT * FROM sys.database_principals WHERE name = N''''''+ @UserName +'''''')''
                        + CHAR(13) + ''BEGIN TRY'' + CHAR(13) + 
                        ''  CREATE USER '' + QUOTENAME(@UserName)

        IF (@LoginName IS NOT NULL)
            SET @messageOut = @messageOut + '' FOR LOGIN '' + QUOTENAME(@LoginName)
        ELSE
            SET @messageOut = @messageOut + '' WITHOUT LOGIN''  

        IF (@DefSchemaName IS NOT NULL)
            SET @messageOut = @messageOut + '' WITH DEFAULT_SCHEMA = ''  + QUOTENAME(@DefSchemaName)

        SET @messageOut = @messageOut + CHAR(13) + ''END TRY'' + CHAR(13) + ''BEGIN CATCH'' + CHAR(13) + ''END CATCH''

        FETCH NEXT FROM user_curs INTO @UserName, @LoginName, @DefSchemaName
    END
    CLOSE user_curs
    DEALLOCATE user_curs

    -- GENERATE ROLES

    SET @messageOut = @messageOut + CHAR(13) + CHAR(13) + ''-- CREATE ROLES '' + CHAR(13)

    SELECT @messageOut = @messageOut + CHAR(13) + ''BEGIN TRY'' + CHAR(13) + 
                        N''EXEC sp_addrolemember N''''''+ rp.name +'''''', N''''''+ mp.name +''''''''
                        + CHAR(13) + ''END TRY'' + CHAR(13) + ''BEGIN CATCH'' + CHAR(13) + ''END CATCH''
    FROM sys.database_role_members drm
    join sys.database_principals rp ON (drm.role_principal_id = rp.principal_id)
    join sys.database_principals mp ON (drm.member_principal_id = mp.principal_id)
    WHERE mp.name NOT IN (N''dbo'')


    -- GENERATE PERMISSIONS

    SET @messageOut = @messageOut + CHAR(13) + CHAR(13) + ''-- CREATE PERMISSIONS '' + CHAR(13)

    SELECT @messageOut = @messageOut + CHAR(13) + ''BEGIN TRY'' + CHAR(13) + 
                        ''  GRANT '' + dp.permission_name collate latin1_general_cs_as +
                        '' ON '' + QUOTENAME(s.name) + ''.'' + QUOTENAME(o.name) + '' TO '' + QUOTENAME(dpr.name)  +
                        + CHAR(13) + ''END TRY'' + CHAR(13) + ''BEGIN CATCH'' + CHAR(13) + ''END CATCH''
    FROM sys.database_permissions AS dp
    INNER JOIN sys.objects AS o ON dp.major_id=o.object_id
    INNER JOIN sys.schemas AS s ON o.schema_id = s.schema_id
    INNER JOIN sys.database_principals AS dpr ON dp.grantee_principal_id=dpr.principal_id
    WHERE dpr.name NOT IN (''public'',''guest'')'

    EXECUTE sp_executesql @tmpStr, N'@messageOut NVARCHAR(MAX) OUTPUT', @messageOut = @tmpstr OUTPUT

    SET @message = @message + @tmpStr

    FETCH NEXT FROM database_curs INTO @DatabaseName
END
CLOSE database_curs
DEALLOCATE database_curs

SELECT @message
declare @DBRoleName varchar(40) = 'yourUserName'
SELECT 'GRANT ' + dbprm.permission_name + ' ON ' + OBJECT_SCHEMA_NAME(major_id) + '.' + OBJECT_NAME(major_id) + ' TO ' + dbrol.name + char(13) COLLATE Latin1_General_CI_AS
from sys.database_permissions dbprm
join sys.database_principals dbrol on
dbprm.grantee_principal_id = dbrol.principal_id
where dbrol.name = @DBRoleName

http://www.sqlserver-dba.com/2014/10/how-to-script-database-role-permissions-and-securables.html

환경 간에 액세스를 복제하는 스크립트를 생성하는 데 적합한 솔루션임을 알게 되었습니다.

언급URL : https://stackoverflow.com/questions/1987190/scripting-sql-server-permissions