пятница, 9 сентября 2011 г.

Трансляция пользователей в SQL 2000 (миграция)

TSQL-скрипт предназначенный для трансляции Windows-пользователей и Windows-групп в SQL Server 2000.

Ссылка на скрипт: http://pastebin.com/hwc4bgZX
Важно: Не забывайте делать резервные копии :)


1. Проблема.
При миграции пользователей между лесами (доменами) основной SID пользователя меняется. Если сохраняется SID-History, то проблем не возникает. Но если далее удалить SID-history, то у пользователя может пропасть доступ к определенным ресурсам. Один из них - SQL-сервер.
Для таких ресурсов как файловые серверы есть соответствующие мастеры для смены основного старого SID в ACL на новый (ADMT, Security Translation Wizard). Но для SQL-а таких средств (известных мне) нет.
Данный скрипт решает эту проблему.

2. Как работает?
Вы запускаете скрипт. Он находит Windows-пользователей (logins) в SQL-сервере и пытается получить всех пользователей из целевого домена (получается смигрированных). Поиск происходит по логинам (sAMAccountName). Если пользователь (login) не создан в SQL, то происходит создание пользователя.
Далее происходит перебор всех баз и связывание пользователей (user) с новыми login'ами, по sid.
Старые пользователи (login) не удаляются из SQL-сервера.
Можно производить трансляцию при миграции баз данных, в том числе и системных (master) между серверами (при использовании локальных аккаунтов в качестве login).


3. Ограничения.
- Работает только с SQL Server 2000.
- Работает только если логины пользователей из старого и нового домена совпадают.
- Не транслирует системные таблицы (master, msdb, model, tempdb

4. Как запустить?
Сначала необходимо изменить переменные @SourceDomain и @TargetDomain на исходный и целевой домен соответственно.
Далее необходимо запустить скрипт. Это можно сделать с помощью инструментов SQL Query Analyzer, osql и др.



--Текст скрипта
---------------------------------------------------------
exec sp_configure 'allow_update',1
reconfigure with override
go

declare @SourceDomain nvarchar(255), @TargetDomain nvarchar(255)
set @SourceDomain = 'INTERMARK'
set @TargetDomain = 'CORP'

select name as SourceName, REPLACE(name,@SourceDomain + '\',@TargetDomain + '\') as TargetName,
    sid as SourceSID, SUSER_SID(REPLACE(name,@SourceDomain + '\',@TargetDomain + '\')) as TargetSID
into #Temp1
from master..syslogins
where (name like (@SourceDomain + '\%') or name like (@TargetDomain+'\%'))
    and SUSER_SID(REPLACE(name,@SourceDomain + '\',@TargetDomain + '\')) is not null
    and isntname = 1

declare Logins cursor local forward_only static
for
    select t1.TargetName
    from #Temp1 t1
    where not exists (select null from #Temp1 t2 where t1.TargetName = t2.SourceName)

open Logins

declare @logname nvarchar(255)

fetch next from Logins into @logname

    while @@FETCH_STATUS = 0
    begin
        exec sp_grantlogin @loginame = @logname
        fetch next from Logins into @logname
    end

close Logins
Deallocate Logins

declare Dbs cursor local forward_only static
for
    select name
    from sysdatabases
    where name not in ('master','model','tempdb','msdb')
    --where name in ('Northwind')

open Dbs

    declare @name sysname
    fetch next from Dbs into @name

    declare @sql_text nvarchar(4000)

    while @@fetch_status=0
    begin
        select 'Обработка базы ' + @name + ':'

        set @sql_text = 'select ' + QUOTENAME(@name,'''') + ' as dbname, ' +
            ' u.name as UserName, t1.SourceSID, t1.TargetSID from #Temp1 as t1 join ' +
            QUOTENAME(@name) + '..sysusers u on t1.SourceSID = u.sid'

        execute(@sql_text)

         set @sql_text = 'update users '  +
             ' set sid = t1.TargetSID' +
             ' from ' + QUOTENAME(@name)+ '..sysusers as users ' +
             ' join #Temp1 t1 on users.sid = t1.SourceSID '
       
        execute(@sql_text)

        fetch next from Dbs into @name
    end

close  Dbs
deallocate  Dbs

drop table #Temp1

exec sp_configure 'allow_update',0
reconfigure with override
go
---------------------------------------------------------

Комментариев нет: