Как клонировать пользователя в SQL Server 2008 R2?
23
Есть ли способ клонировать безопасность и разрешения пользователей в Microsoft SQL Server, предпочтительно используя графический интерфейс SQL Server Management Studio?
Примечание. Приведенный ниже скрипт фактически не устанавливает разрешения для чего-либо, он просто создает скрипт, который можно скопировать и вставить в новый запрос, который затем можно отредактировать перед выполнением.
Нижеприведенный скрипт поможет вам скопировать / клонировать разрешения одного пользователя другому:
--- 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 ONDECLARE@OldUser sysname,@NewUser sysname
SET@OldUser ='userOLD'--The user or role from which to copy the permissions fromSET@NewUser ='userNEW'--The user or role to which to copy the permissions toSELECT'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
ORDERBY rm.role_principal_id ASCSELECTCASEWHEN 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)+CASEWHEN cl.column_id ISNULLTHEN SPACE(0)ELSE'('+ QUOTENAME(cl.name)+')'END+ SPACE(1)+'TO'+ SPACE(1)+ QUOTENAME(@NewUser)COLLATE database_default
+CASEWHEN perm.state <>'W'THEN SPACE(0)ELSE SPACE(1)+'WITH GRANT OPTION'ENDAS'--Object Level Permissions'FROM sys.database_permissions AS perm
INNERJOIN
sys.objects AS obj
ON perm.major_id = obj.[object_id]INNERJOIN
sys.database_principals AS usr
ON perm.grantee_principal_id = usr.principal_id
LEFTJOIN
sys.columns AS cl
ON cl.column_id = perm.minor_id AND cl.[object_id]= perm.major_id
WHERE usr.name =@OldUser
ORDERBY perm.permission_name ASC, perm.state_desc ASCSELECTCASEWHEN 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
+CASEWHEN perm.state <>'W'THEN SPACE(0)ELSE SPACE(1)+'WITH GRANT OPTION'ENDAS'--Database Level Permissions'FROM sys.database_permissions AS perm
INNERJOIN
sys.database_principals AS usr
ON perm.grantee_principal_id = usr.principal_id
WHERE usr.name =@OldUser
AND perm.major_id =0ORDERBY perm.permission_name ASC, perm.state_desc ASC
@sweetritz Если бы существовал графический интерфейс для клонирования пользователя, вам не нужно было бы задавать вопрос, потому что вы можете просто нажать кнопку. Нет Просто потому, что вы «не разбираетесь в кодах», нет оправдания тому, чтобы не учиться быть лучше ...
Аарон Бертран
6
Не ограничивайтесь только использованием GUI. GUI хорош для новичка, но он ограничен. Для вашей задачи вышеприведенный скрипт просто сгенерирует реальные скрипты, которые вы можете использовать для создания / клонирования пользователя .
Кин Шах
1
спасибо Аарону за совет :) и @Kin спасибо за помощь, это был очень быстрый ответ, высоко ценится :) :)
sweetritz
2
Я думаю, что должно быть ясно, что запуск вышеупомянутого сценария фактически не устанавливает разрешения ни для чего, он просто создает сценарий, который можно скопировать и вставить в новый запрос, который затем можно отредактировать перед выполнением. Я просто использовал его сам, и он работал отлично! Отличная экономия времени!
Алан Фишер
2
@AlanFisher спасибо за ваш комментарий и рад, что он помог вам. Обновил мой ответ, чтобы отразить ваш комментарий. Благодарность !
Я НЕ автор этого сценария. Сценарий вставлен по этой ссылке в блоге Павла Павловского, см. Ссылку для получения дополнительной информации о том, как использовать сценарий.
USE[master]
GO
--============================================-- Author: Pavel Pawlowski-- Created: 2010/04/16-- Description: Copies rights of old user to new user--==================================================CREATEPROCEDURE 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)ASBEGINSET NOCOUNT ONCREATETABLE#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(NOTEXISTS(SELECT1FROM sys.database_principals where name =@oldUser))BEGINSET@msg ='Source user '+ QUOTENAME(@oldUser)+' doesn''t exists in database '+@dbName
RAISERROR(@msg,11,1)RETURNENDINSERTINTO#output(command)SELECT'--Database Context'AS command UNIONALLSELECT'USE'+ SPACE(1)+@dbName UNIONALLSELECT'SET XACT_ABORT ON'IF(ISNULL(@NewLoginName,'')<>'')BEGINSET@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
ENDINSERTINTO#output(command)SELECT'--Cloning permissions from'+ SPACE(1)+ QUOTENAME(@OldUser)+ SPACE(1)+'to'+ SPACE(1)+ QUOTENAME(@NewUser)INSERTINTO#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
INSERTINTO#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
INSERTINTO#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 CURSORFORSELECT command FROM#output
OPEN cr
FETCH NEXT FROM cr INTO@command
SET@sql =''WHILE@@FETCH_STATUS =0BEGINIF(@printOnly ISNOTNULL)PRINT@command
SET@sql =@sql +@command + CHAR(13)+ CHAR(10)FETCH NEXT FROM cr INTO@command
ENDCLOSE cr
DEALLOCATE cr
IF(@printOnly ISNULLOR@printOnly =0)EXEC(@sql)DROPTABLE#output
END
GO
EXECUTE sp_ms_marksystemobject 'dbo.sp_CloneRights'
GO
Щелкните правой кнопкой мыши базу данных в обозревателе объектов
Задачи-> Создать сценарии ...
Выберите раздел «Только пользователи» и завершите работу мастера как есть.
Примечание: наконец вы получаете сценарий для всех пользователей и их роли почти готовы. но это не создаст сценарий для предоставления разрешения « Выполнить» для хранимых процедур, даже если для параметра «Разрешения на уровне объекта» выбрано значение «истина».
Это не будет работать: он не будет генерировать скрипт для предоставления выполнения хранимым процедурам
Макс
Да ты прав. Я добавил некоторые уточнения
Иман Абиди
0
Основываясь на потрясающем ответе @ Kin-shah, я написал скрипт, который может копировать разрешения всех баз данных в одном экземпляре сервера sql. Он намного хуже читается, но может пригодиться, если у вас много пользователей и много баз данных:
USE master
GO
IFEXISTS(SELECT1FROM INFORMATION_SCHEMA.ROUTINES r WHERE r.ROUTINE_NAME ='clone_user')DROPPROCEDURE clone_user
GO
CREATEPROCEDURE clone_user @database sysname,@OldUser sysname,@NewUser sysname ASBEGINDECLARE@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'''DROPPROCEDURE clone_user
Вот очень хороший сценарий Павла Павловского для выполнения этой работы: http://www.pawlowski.cz/2011/03/cloning-user-rights-database/
Основное преимущество:
Я НЕ автор этого сценария. Сценарий вставлен по этой ссылке в блоге Павла Павловского, см. Ссылку для получения дополнительной информации о том, как использовать сценарий.
источник
Примечание: наконец вы получаете сценарий для всех пользователей и их роли почти готовы. но это не создаст сценарий для предоставления разрешения « Выполнить» для хранимых процедур, даже если для параметра «Разрешения на уровне объекта» выбрано значение «истина».
источник
Основываясь на потрясающем ответе @ Kin-shah, я написал скрипт, который может копировать разрешения всех баз данных в одном экземпляре сервера sql. Он намного хуже читается, но может пригодиться, если у вас много пользователей и много баз данных:
источник