Es muy habitual tener que pasar una BBDD de un servidor a otro, y nos encontramos siempre con el problema de los usuarios que se encuentran dados de alta en la instancia de SQL Server.
Los usuarios de dominio no suponen un problema ya que darlos de alta de nuevo no requiere conocer la contraseña de usuario, pero los usuarios dados de alta directamente en SQL Server no podremos volverlos a crear si no conocemos la password de cada usuario.
Para solucionar este problema existe una forma de extraer los usuarios de una instancia con las password (cifradas) y poderlas importar a continuación en la nueva instancia.
Con el procedimiento que vamos a explicar aquí tendremos la ventaja de que exportaremos también el "sid" del usuario, con lo que al importar los usuarios, la BBDD que estamos migrando los reconocerá como suyos. Si no hiciésemos esto, al crear los nuevos usuarios a mano, tendríamos que eliminar los usuarios que tiene la BBDD, ya que los "sid" no coincidirían y los usuarios a nivel de la Instancia y los usuarios a nivel de BBDD se tomarían como usuarios distintos.
SQL SERVER 2005
Pasos a seguir:
- Ejecutar la consulta (más abajo). Esto creará 2 procedimientos almacenados en la BBDD Master: sp_help_revlogin y sp_hexadecimal.
- Pulsamos botón derecho sobre sp_help_revlogin y seleccionamos "Execute Stored Procedure". Esto nos dará como resultado una nueva consulta (query).
- Ejecutamos la nueva consulta generada y y al hacerlo nos devuelve otra consulta con la que podremos generar los usuarios.
- Copiamos la consulta de generación de usuarios y la ejecutamos en la Instancia del servidor destino.
A continuación os pongo la consulta con la que comenzaremos el proceso. Os comento que también nos va a rescatar el idioma y la bbdd por defecto de cada usuario.
--*************************************************************
--*************************************************************
USE master
GO
IF OBJECT_ID ('sp_hexadecimal') IS NOT NULL
DROP PROCEDURE
sp_hexadecimal
GO
CREATE PROCEDURE 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
GO
IF OBJECT_ID ('sp_help_revlogin') IS NOT NULL
DROP PROCEDURE
sp_help_revlogin
GO
CREATE PROCEDURE sp_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
@language varchar (128)
DECLARE
@dbname varchar (128)
IF (@login_name IS NULL)
DECLARE login_curs CURSOR
FOR
SELECT p.sid, p.name, p.type, p.is_disabled, l.hasaccess, l.denylogin, l.language, l.dbname
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, l.hasaccess, l.denylogin, l.language, l.dbname
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, @hasaccess, @denylogin, @language, @dbname
IF (@@fetch_status = -1)
BEGIN
PRINT 'No login(s) found.'
CLOSE login_curs
DEALLOCATE login_curs
RETURN -1
END
SET
@tmpstr = '/*
sp_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'
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 = 'CREATE LOGIN ' + QUOTENAME( @name )
+ ' WITH PASSWORD = '
+ @PWD_string
+ ' HASHED, SID = '
+ @SID_string
+ ',
DEFAULT_LANGUAGE = [' + @language
+ '],
DEFAULT_DATABASE = [' + @dbname + ']'
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 has 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,
@hasaccess, @denylogin,
@language, @dbname
END
CLOSE
login_curs
DEALLOCATE
login_curs
RETURN 0
GO
--*************************************************************
--*************************************************************
SQL SERVER 2000
En esta versión de SQL Server, la cosa cambia.
Primero ejecutaremos una consulta (más abajo), que nos dará como resultado una tabla en la que cada fila de dicha tabla representa una consulta de creación de usuario.
Lo mejor es seleccionar toda la tabla, copiarla (CTRL+C) y pegarla en una nueva consulta en la instancia del servidor destino. La ejecutamos y nos generará los usuarios.
select 'CREATE LOGIN [' + l.name + '] WITH PASSWORD = ', (CAST(l.password as varbinary(256))), ' HASHED, SID = ', CAST(l.sid as varbinary), ', CHECK_EXPIRATION=OFF, CHECK_POLICY=OFF ' + 'GO ' from master..syslogins l where
l.isntname + l.isntgroup = 0
Muchas gracias buen aporte
ResponderEliminar