Skip to content

Commit 4364d2c

Browse files
committed
sp_DatabaseRestore.sql: Add @FixOrphanUsers option
Implements issue #3267 Fix database_principals that do not match server_principals after a cross-server restore.
1 parent 6578594 commit 4364d2c

1 file changed

Lines changed: 49 additions & 11 deletions

File tree

sp_DatabaseRestore.sql

Lines changed: 49 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@ ALTER PROCEDURE [dbo].[sp_DatabaseRestore]
1111
@MoveDataDrive NVARCHAR(260) = NULL,
1212
@MoveLogDrive NVARCHAR(260) = NULL,
1313
@MoveFilestreamDrive NVARCHAR(260) = NULL,
14-
@MoveFullTextCatalogDrive NVARCHAR(260) = NULL,
15-
@BufferCount INT = NULL,
16-
@MaxTransferSize INT = NULL,
17-
@BlockSize INT = NULL,
14+
@MoveFullTextCatalogDrive NVARCHAR(260) = NULL,
15+
@BufferCount INT = NULL,
16+
@MaxTransferSize INT = NULL,
17+
@BlockSize INT = NULL,
1818
@TestRestore BIT = 0,
1919
@RunCheckDB BIT = 0,
2020
@RestoreDiff BIT = 0,
@@ -27,15 +27,16 @@ ALTER PROCEDURE [dbo].[sp_DatabaseRestore]
2727
@StopAt NVARCHAR(14) = NULL,
2828
@OnlyLogsAfter NVARCHAR(14) = NULL,
2929
@SimpleFolderEnumeration BIT = 0,
30-
@SkipBackupsAlreadyInMsdb BIT = 0,
31-
@DatabaseOwner sysname = NULL,
32-
@SetTrustworthyON BIT = 0,
30+
@SkipBackupsAlreadyInMsdb BIT = 0,
31+
@DatabaseOwner sysname = NULL,
32+
@SetTrustworthyON BIT = 0,
33+
@FixOrphanUsers BIT = 0,
3334
@Execute CHAR(1) = Y,
34-
@FileExtensionDiff NVARCHAR(128) = NULL,
35+
@FileExtensionDiff NVARCHAR(128) = NULL,
3536
@Debug INT = 0,
3637
@Help BIT = 0,
3738
@Version VARCHAR(30) = NULL OUTPUT,
38-
@VersionDate DATETIME = NULL OUTPUT,
39+
@VersionDate DATETIME = NULL OUTPUT,
3940
@VersionCheckMode BIT = 0
4041
AS
4142
SET NOCOUNT ON;
@@ -1374,7 +1375,6 @@ BEGIN
13741375
AND REPLACE( RIGHT( REPLACE( fl.BackupFile, RIGHT( fl.BackupFile, PATINDEX( '%_[0-9][0-9]%', REVERSE( fl.BackupFile ) ) ), '' ), 16 ), '_', '' ) > @StopAt
13751376
ORDER BY BackupFile;
13761377
END
1377-
13781378
IF @ExtraLogFile IS NULL
13791379
BEGIN
13801380
DELETE fl
@@ -1584,7 +1584,45 @@ IF @DatabaseOwner IS NOT NULL
15841584
END
15851585
END;
15861586

1587-
-- If test restore then blow the database away (be careful)
1587+
-- Link a user entry in the sys.database_principals system catalog view in the restored database to a SQL Server login of the same name
1588+
IF @FixOrphanUsers = 1
1589+
BEGIN
1590+
SET @sql = N'
1591+
-- Fixup Orphan Users by setting database user sid to match login sid
1592+
DECLARE @FixOrphansSql NVARCHAR(MAX);
1593+
DECLARE @OrphanUsers TABLE (SqlToExecute NVARCHAR(MAX));
1594+
USE ' + @RestoreDatabaseName + ';
1595+
1596+
INSERT @OrphanUsers
1597+
SELECT ''ALTER USER ['' + d.name + ''] WITH LOGIN = ['' + d.name + '']; ''
1598+
FROM sys.database_principals d
1599+
INNER JOIN master.sys.server_principals s ON d.name COLLATE DATABASE_DEFAULT = s.name COLLATE DATABASE_DEFAULT
1600+
WHERE d.type_desc = ''SQL_USER''
1601+
AND d.name NOT IN (''guest'',''dbo'')
1602+
AND d.sid <> s.sid
1603+
ORDER BY d.name;
1604+
1605+
SELECT @FixOrphansSql = (SELECT SqlToExecute AS [text()] FROM @OrphanUsers FOR XML PATH (''''), TYPE).value(''text()[1]'',''NVARCHAR(MAX)'');
1606+
1607+
IF @FixOrphansSql IS NULL
1608+
PRINT ''No orphan users require a sid fixup.'';
1609+
ELSE
1610+
BEGIN
1611+
PRINT ''Fix Orphan Users: '' + @FixOrphansSql;
1612+
EXECUTE(@FixOrphansSql);
1613+
END;'
1614+
1615+
IF @Debug = 1 OR @Execute = 'N'
1616+
BEGIN
1617+
IF @sql IS NULL PRINT '@sql is NULL for Fix Orphan Users';
1618+
PRINT @sql;
1619+
END;
1620+
1621+
IF @Debug IN (0, 1) AND @Execute = 'Y'
1622+
EXECUTE [dbo].[CommandExecute] @DatabaseContext = 'master', @Command = @sql, @CommandType = 'UPDATE', @Mode = 1, @DatabaseName = @UnquotedRestoreDatabaseName, @LogToTable = 'Y', @Execute = 'Y';
1623+
END;
1624+
1625+
-- If test restore then blow the database away (be careful)
15881626
IF @TestRestore = 1
15891627
BEGIN
15901628
SET @sql = N'DROP DATABASE ' + @RestoreDatabaseName + NCHAR(13);

0 commit comments

Comments
 (0)