¿Hay alguna forma de clonar la seguridad y los permisos de los usuarios en Microsoft SQL Server, preferiblemente usando la GUI de SQL Server Management Studio?
Nota: El siguiente script en realidad no establece los permisos en nada, solo crea el script que puede copiarse y pegarse en una nueva consulta, que luego puede editarse antes de ejecutarse.
El siguiente script lo ayudará a copiar / clonar permisos de un usuario a otro:
--- 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 Si hubiera una GUI para clonar a un usuario, no necesitaría hacer la pregunta, ya que podría presionar el botón. No hay El hecho de que "no seas bueno con los códigos" no es excusa para no aprender a ser mejor ...
Aaron Bertrand
66
No te limites a solo usar la GUI. La GUI es buena para principiantes, pero es limitada. Para su tarea, el script anterior solo generará scripts reales que puede usar para crear / clonar usuarios .
Kin Shah
1
gracias Aaron por el consejo :) y @Kin gracias por la ayuda, esa fue una respuesta muy rápida, muy apreciada :) :)
sweetritz
2
Creo que debe quedar claro que ejecutar el script anterior en realidad no establece los permisos en nada, solo crea el script que se puede copiar y pegar en una nueva consulta, que luego se puede editar antes de ejecutarlo. ¡Lo usé yo mismo y funcionó perfectamente! Gran ahorro de tiempo!
Alan Fisher
2
@AlanFisher gracias por tu comentario y me alegro de que te haya ayudado. Actualicé mi respuesta para reflejar tu comentario. Gracias !
NO soy el autor de este script. El script se copia de este enlace en el blog de Pavel Pawlowski. Consulte el enlace para obtener más información sobre cómo usar el script.
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
Haga clic derecho en la base de datos en el Explorador de objetos
Tareas-> Generar guiones ...
Seleccione la sección Solo usuarios y finalice el asistente tal como está
Nota: finalmente obtienes el script para toda la creación de usuarios y sus roles casi listos. pero esto no creará una secuencia de comandos para Conceder permiso de ejecución para procedimientos almacenados, incluso si selecciona Permisos de nivel de objeto de secuencia de comandos en verdadero.
No funcionará: no generará script para otorgar ejecución en procedimientos almacenados
Max
Sí, tiene usted razón. He agregado algunas aclaraciones
Iman Abidi,
0
Basado en la increíble respuesta de @ Kin-shah, escribí un script que puede copiar permisos de todas las bases de datos en una instancia de servidor sql. Es mucho peor legible, pero puede ser útil si tiene muchos usuarios y muchas bases de datos:
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
Aquí hay un script muy bueno de Pavel Pawlowski para hacer el trabajo: http://www.pawlowski.cz/2011/03/cloning-user-rights-database/
Ventaja principal:
NO soy el autor de este script. El script se copia de este enlace en el blog de Pavel Pawlowski. Consulte el enlace para obtener más información sobre cómo usar el script.
fuente
Nota: finalmente obtienes el script para toda la creación de usuarios y sus roles casi listos. pero esto no creará una secuencia de comandos para Conceder permiso de ejecución para procedimientos almacenados, incluso si selecciona Permisos de nivel de objeto de secuencia de comandos en verdadero.
fuente
Basado en la increíble respuesta de @ Kin-shah, escribí un script que puede copiar permisos de todas las bases de datos en una instancia de servidor sql. Es mucho peor legible, pero puede ser útil si tiene muchos usuarios y muchas bases de datos:
fuente