Jawaban:
Catatan: Skrip di bawah ini sebenarnya tidak mengatur izin apa pun, itu hanya membuat skrip yang dapat disalin dan ditempelkan ke kueri baru, yang kemudian dapat diedit sebelum dieksekusi.
Skrip di bawah ini akan membantu Anda menyalin / mengkloning izin satu pengguna ke pengguna lain:
--- To copy permissions of one user/role to another user/role.
USE database_name -- Use the database from which you want to extract the permissions
GO
SET NOCOUNT ON
DECLARE @OldUser sysname, @NewUser sysname
SET @OldUser = 'userOLD' --The user or role from which to copy the permissions from
SET @NewUser = 'userNEW' --The user or role to which to copy the permissions to
SELECT 'USE' + SPACE(1) + QUOTENAME(DB_NAME()) AS '--Database Context'
SELECT '--Cloning permissions from' + SPACE(1) + QUOTENAME(@OldUser) + SPACE(1) + 'to' + SPACE(1) + QUOTENAME(@NewUser) AS '--Comment'
SELECT 'EXEC sp_addrolemember @rolename ='
+ SPACE(1) + QUOTENAME(USER_NAME(rm.role_principal_id), '''') + ', @membername =' + SPACE(1) + QUOTENAME(@NewUser, '''') AS '--Role Memberships'
FROM sys.database_role_members AS rm
WHERE USER_NAME(rm.member_principal_id) = @OldUser
ORDER BY rm.role_principal_id ASC
SELECT CASE WHEN perm.state <> 'W' THEN perm.state_desc ELSE 'GRANT' END
+ SPACE(1) + perm.permission_name + SPACE(1) + 'ON ' + QUOTENAME(SCHEMA_NAME(obj.schema_id)) + '.' + QUOTENAME(obj.name)
+ CASE WHEN cl.column_id IS NULL THEN SPACE(0) ELSE '(' + QUOTENAME(cl.name) + ')' END
+ SPACE(1) + 'TO' + SPACE(1) + QUOTENAME(@NewUser) COLLATE database_default
+ CASE WHEN perm.state <> 'W' THEN SPACE(0) ELSE SPACE(1) + 'WITH GRANT OPTION' END AS '--Object Level Permissions'
FROM sys.database_permissions AS perm
INNER JOIN
sys.objects AS obj
ON perm.major_id = obj.[object_id]
INNER JOIN
sys.database_principals AS usr
ON perm.grantee_principal_id = usr.principal_id
LEFT JOIN
sys.columns AS cl
ON cl.column_id = perm.minor_id AND cl.[object_id] = perm.major_id
WHERE usr.name = @OldUser
ORDER BY perm.permission_name ASC, perm.state_desc ASC
SELECT CASE WHEN perm.state <> 'W' THEN perm.state_desc ELSE 'GRANT' END
+ SPACE(1) + perm.permission_name + SPACE(1)
+ SPACE(1) + 'TO' + SPACE(1) + QUOTENAME(@NewUser) COLLATE database_default
+ CASE WHEN perm.state <> 'W' THEN SPACE(0) ELSE SPACE(1) + 'WITH GRANT OPTION' END AS '--Database Level Permissions'
FROM sys.database_permissions AS perm
INNER JOIN
sys.database_principals AS usr
ON perm.grantee_principal_id = usr.principal_id
WHERE usr.name = @OldUser
AND perm.major_id = 0
ORDER BY perm.permission_name ASC, perm.state_desc ASC
Berikut ini adalah skrip yang sangat bagus dari Pavel Pawlowski untuk melakukan pekerjaan itu: http://www.pawlowski.cz/2011/03/cloning-user-rights-database/
Keuntungan utama:
Saya TIDAK penulis skrip ini. Skrip disalin dari tautan ini di blog Pavel Pawlowski, lihat tautan untuk informasi lebih lanjut tentang cara menggunakan skrip.
USE [master]
GO
--============================================
-- Author: Pavel Pawlowski
-- Created: 2010/04/16
-- Description: Copies rights of old user to new user
--==================================================
CREATE PROCEDURE sp_CloneRights (
@oldUser sysname, --Old user from which to copy right
@newUser sysname, --New user to which copy rights
@printOnly bit = 1, --When 1 then only script is printed on screen, when 0 then also script is executed, when NULL, script is only executed and not printed
@NewLoginName sysname = NULL --When a NewLogin name is provided also a creation of user is part of the final script
)
AS
BEGIN
SET NOCOUNT ON
CREATE TABLE #output (
command nvarchar(4000)
)
DECLARE
@command nvarchar(4000),
@sql nvarchar(max),
@dbName nvarchar(128),
@msg nvarchar(max)
SELECT
@sql = N'',
@dbName = QUOTENAME(DB_NAME())
IF (NOT EXISTS(SELECT 1 FROM sys.database_principals where name = @oldUser))
BEGIN
SET @msg = 'Source user ' + QUOTENAME(@oldUser) + ' doesn''t exists in database ' + @dbName
RAISERROR(@msg, 11,1)
RETURN
END
INSERT INTO #output(command)
SELECT '--Database Context' AS command UNION ALL
SELECT 'USE' + SPACE(1) + @dbName UNION ALL
SELECT 'SET XACT_ABORT ON'
IF (ISNULL(@NewLoginName, '') <> '')
BEGIN
SET @sql = N'USE ' + @dbName + N';
IF NOT EXISTS (SELECT 1 FROM sys.database_principals WHERE name = @newUser)
BEGIN
INSERT INTO #output(command)
SELECT ''--Create user'' AS command
INSERT INTO #output(command)
SELECT
''CREATE USER '' + QUOTENAME(@NewUser) + '' FOR LOGIN '' + QUOTENAME(@NewLoginName) +
CASE WHEN ISNULL(default_schema_name, '''') <> '''' THEN '' WITH DEFAULT_SCHEMA = '' + QUOTENAME(dp.default_schema_name)
ELSE ''''
END AS Command
FROM sys.database_principals dp
INNER JOIN sys.server_principals sp ON dp.sid = sp.sid
WHERE dp.name = @OldUser
END'
EXEC sp_executesql @sql, N'@OldUser sysname, @NewUser sysname, @NewLoginName sysname', @OldUser = @OldUser, @NewUser = @NewUser, @NewLoginName=@NewLoginName
END
INSERT INTO #output(command)
SELECT '--Cloning permissions from' + SPACE(1) + QUOTENAME(@OldUser) + SPACE(1) + 'to' + SPACE(1) + QUOTENAME(@NewUser)
INSERT INTO #output(command)
SELECT '--Role Memberships' AS command
SET @sql = N'USE ' + @dbName + N';
INSERT INTO #output(command)
SELECT ''EXEC sp_addrolemember @rolename =''
+ SPACE(1) + QUOTENAME(USER_NAME(rm.role_principal_id), '''''''') + '', @membername ='' + SPACE(1) + QUOTENAME(@NewUser, '''''''') AS command
FROM sys.database_role_members AS rm
WHERE USER_NAME(rm.member_principal_id) = @OldUser
ORDER BY rm.role_principal_id ASC'
EXEC sp_executesql @sql, N'@OldUser sysname, @NewUser sysname', @OldUser = @OldUser, @NewUser = @NewUser
INSERT INTO #output(command)
SELECT '--Object Level Permissions'
SET @sql = N'USE ' + @dbName + N';
INSERT INTO #output(command)
SELECT CASE WHEN perm.state <> ''W'' THEN perm.state_desc ELSE ''GRANT'' END
+ SPACE(1) + perm.permission_name + SPACE(1) + ''ON '' + QUOTENAME(USER_NAME(obj.schema_id)) + ''.'' + QUOTENAME(obj.name)
+ CASE WHEN cl.column_id IS NULL THEN SPACE(0) ELSE ''('' + QUOTENAME(cl.name) + '')'' END
+ SPACE(1) + ''TO'' + SPACE(1) + QUOTENAME(@NewUser) COLLATE database_default
+ CASE WHEN perm.state <> ''W'' THEN SPACE(0) ELSE SPACE(1) + ''WITH GRANT OPTION'' END
FROM sys.database_permissions AS perm
INNER JOIN
sys.objects AS obj
ON perm.major_id = obj.[object_id]
INNER JOIN
sys.database_principals AS usr
ON perm.grantee_principal_id = usr.principal_id
LEFT JOIN
sys.columns AS cl
ON cl.column_id = perm.minor_id AND cl.[object_id] = perm.major_id
WHERE usr.name = @OldUser
ORDER BY perm.permission_name ASC, perm.state_desc ASC'
EXEC sp_executesql @sql, N'@OldUser sysname, @NewUser sysname', @OldUser = @OldUser, @NewUser = @NewUser
INSERT INTO #output(command)
SELECT N'--Database Level Permissions'
SET @sql = N'USE ' + @dbName + N';
INSERT INTO #output(command)
SELECT CASE WHEN perm.state <> ''W'' THEN perm.state_desc ELSE ''GRANT'' END
+ SPACE(1) + perm.permission_name + SPACE(1)
+ SPACE(1) + ''TO'' + SPACE(1) + QUOTENAME(@NewUser) COLLATE database_default
+ CASE WHEN perm.state <> ''W'' THEN SPACE(0) ELSE SPACE(1) + ''WITH GRANT OPTION'' END
FROM sys.database_permissions AS perm
INNER JOIN
sys.database_principals AS usr
ON perm.grantee_principal_id = usr.principal_id
WHERE usr.name = @OldUser
AND perm.major_id = 0
ORDER BY perm.permission_name ASC, perm.state_desc ASC'
EXEC sp_executesql @sql, N'@OldUser sysname, @NewUser sysname', @OldUser = @OldUser, @NewUser = @NewUser
DECLARE cr CURSOR FOR
SELECT command FROM #output
OPEN cr
FETCH NEXT FROM cr INTO @command
SET @sql = ''
WHILE @@FETCH_STATUS = 0
BEGIN
IF (@printOnly IS NOT NULL)
PRINT @command
SET @sql = @sql + @command + CHAR(13) + CHAR(10)
FETCH NEXT FROM cr INTO @command
END
CLOSE cr
DEALLOCATE cr
IF (@printOnly IS NULL OR @printOnly = 0)
EXEC (@sql)
DROP TABLE #output
END
GO
EXECUTE sp_ms_marksystemobject 'dbo.sp_CloneRights'
GO
Catatan: akhirnya Anda mendapatkan skrip untuk semua kreasi pengguna dan peran mereka hampir siap. tetapi ini tidak akan membuat skrip untuk Pemberian izin Menjalankan Prosedur untuk Stored bahkan jika Anda Memilih Skrip Izin Tingkat Objek untuk true.
Berdasarkan jawaban luar biasa @ Kin-shah, saya menulis sebuah skrip, yang dapat menyalin izin semua database dalam satu contoh server sql. Ini jauh lebih buruk dibaca, tetapi mungkin berguna, jika Anda memiliki banyak pengguna dan banyak basis data:
USE master
GO
IF EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.ROUTINES r WHERE r.ROUTINE_NAME = 'clone_user')
DROP PROCEDURE clone_user
GO
CREATE PROCEDURE clone_user @database sysname, @OldUser sysname, @NewUser sysname AS BEGIN
DECLARE @sql nvarchar(max)
SET @sql = '
USE '+@database+'
DECLARE @database sysname = '''+@database+'''
DECLARE @OldUser sysname = '''+@OldUser+'''
DECLARE @NewUser sysname = '''+@NewUser+'''
SET NOCOUNT ON
SELECT ''EXEC sp_addrolemember @rolename =''
+ SPACE(1) + QUOTENAME(USER_NAME(rm.role_principal_id), '''''''') + '', @membername ='' + SPACE(1) + QUOTENAME(@NewUser, '''''''') AS ''--Role Memberships''
INTO #roles
FROM sys.database_role_members AS rm
WHERE USER_NAME(rm.member_principal_id) = @OldUser
ORDER BY rm.role_principal_id ASC
SELECT CASE WHEN perm.state <> ''W'' THEN perm.state_desc ELSE ''GRANT'' END
+ SPACE(1) + perm.permission_name + SPACE(1) + ''ON '' + QUOTENAME(USER_NAME(obj.schema_id)) + ''.'' + QUOTENAME(obj.name)
+ CASE WHEN cl.column_id IS NULL THEN SPACE(0) ELSE ''('' + QUOTENAME(cl.name) + '')'' END
+ SPACE(1) + ''TO'' + SPACE(1) + QUOTENAME(@NewUser) COLLATE database_default
+ CASE WHEN perm.state <> ''W'' THEN SPACE(0) ELSE SPACE(1) + ''WITH GRANT OPTION'' END AS ''--Object Level Permissions''
INTO #grant1
FROM sys.database_permissions AS perm
INNER JOIN
sys.objects AS obj
ON perm.major_id = obj.[object_id]
INNER JOIN
sys.database_principals AS usr
ON perm.grantee_principal_id = usr.principal_id
LEFT JOIN
sys.columns AS cl
ON cl.column_id = perm.minor_id AND cl.[object_id] = perm.major_id
WHERE usr.name = @OldUser
ORDER BY perm.permission_name ASC, perm.state_desc ASC
SELECT CASE WHEN perm.state <> ''W'' THEN perm.state_desc ELSE ''GRANT'' END
+ SPACE(1) + perm.permission_name + SPACE(1)
+ SPACE(1) + ''TO'' + SPACE(1) + QUOTENAME(@NewUser) COLLATE database_default
+ CASE WHEN perm.state <> ''W'' THEN SPACE(0) ELSE SPACE(1) + ''WITH GRANT OPTION'' END AS ''--Database Level Permissions''
INTO #grant2
FROM sys.database_permissions AS perm
INNER JOIN
sys.database_principals AS usr
ON perm.grantee_principal_id = usr.principal_id
WHERE usr.name = @OldUser
AND perm.major_id = 0
ORDER BY perm.permission_name ASC, perm.state_desc ASC
IF EXISTS (SELECT * FROM #roles UNION ALL SELECT * FROM #grant1 UNION ALL SELECT * FROM #grant2) BEGIN
SELECT ''USE ''+@database AS ''-- '+@database+'/'+@OldUser+''' INTO #tmp
SELECT * FROM #tmp UNION ALL SELECT * FROM #roles UNION ALL SELECT * FROM #grant1 UNION ALL SELECT * FROM #grant2
END
'
EXECUTE sp_executesql @sql
END
GO
EXEC sp_MSforeachdb 'EXECUTE [dbo].[clone_user] ?, ''OldUser'', ''NewUser'''
DROP PROCEDURE clone_user