Многие организации, сделавшие свой выбор в пользу ActiveDirectory (AD), переходили на новую систему, выбрав методику запуска нового домена AD, работающего параллельно со своим существующим доменом Windows NT40. Администраторы создавали новые учетные записи AD, клонируя или копируя учетные записи NT так, чтобы они совпадали по имени, (т.е.NT4DOMNEUBAUER становился ADDOMNEUBAUER) и чтобы имели одинаковые пароли. Когда я выполнял такой тип миграции, я предпочел отключить учетные записи в AD, пока в них нет необходимости. Это особенно важно в тех случаях, когда я создавал все записи в одно время, а затем позже разрешал пользователям доступ к их учетным записям. Отключение учетных записей позволяет избежать общей проблемы миграции, которую можно выразить фразой типа: «Мои ярлыки приложений на рабочем столе отсутствуют ». Причины этой проблемы я объясню в следующем разделе. Такой подход к миграции имеет свои преимущества, но при этом возникает проблема последующей активации учётных записей, превращающаяся в рутинную работу для администратора. Поэтому я создал сценарий, который упростил мне эту операцию.

Пустые профили

Когда кто-либо регистрируется на рабочей станции Windows, то создается профиль пользователя, связанный с авторизованной учетной записью этого пользователя, а затем этот профиль используется для сохранения информации, специфичной для пользователя. Например, если я регистрируюсь на моей рабочей станции под своей учетной записью NT4DOMNEUBAUER, настраиваю сетевой принтер, задаю три постоянных подключения к сетевым дискам и создаю на своем рабочем столе ярлыки для наиболее часто используемых мной приложений, WINDOWS сохраняет установки в профиле пользователя, связанного с моей учетной записью NT4DOMNEUBAUER. Поэтому все мои установки доступны каждый раз, когда я регистрируюсь на станции. Когда я зарегистрируюсь на станции под своей новой учётной записью ADDOMNEUBAUER, WINDOWS создаст пустой профиль и свяжет его с учётной записью ADDOMNEUBAUER . Этот профиль не будет содержать настроек, сделанных мной во время регистрации через учётную запись NT4DOM/NEUBAUER .

Хороший план миграции должен включать в себя средства копирования старых профилей. Эти средства должны обеспечить доступность установок из старых профилей для созданных профилей пользователей AD и сделать миграцию в максимальной степени прозрачной для пользователя. Проблема многих миграций состоит в том, что пользователи регистрируются на рабочих станциях с новыми учётными записями раньше того, как информация из старых профилей будет скопирована в профиль новой учётной записи. Когда подобное случается, WINDOWS создает пустой профиль, и первое, что видит пользователь - это отсутствующие на его рабочем столе ярлыки для запуска приложений.

Отключив учетные записи AD, вы можете предотвратить преждевременную регистрацию до тех пор, пока вы не закончите процесс копирования профилей на определенную рабочую станцию с заданным пользователем. Вам также необходимо знать, когда разрешить использование новой учетной записи пользователя. Я решил эту проблему, переложив задачу копирования профилей на сторону пользователя, а затем использовал сценарий Active Server Pages (ASP) на выводящейся пользователю WEB-странице. Для активации новых учетных записей использовался командный файл, показанный на листинге 1. Пользователь запускал утилиту переноса профилей, например update.exe из пакета Quest Migrator компании Quest Software. Вы можете распространить этот пакетный файл, используя сценарий регистрации, воспользоваться возможностями Microsoft Systems Management Server (SMS), либо предоставив пользователям возможность запустить его с Web-сайта. Когда Migrator заканчивает дублирование профилей, пакетный файл запускает Microsoft Internet Explorer (IE) и открываетASP Web-страницу на внутреннем Web-сервере. ASP-страница выполняет две функции. Во-первых, она выводит пользователю сообщение о том, что его учетная запись успешно перенесена, во-вторых, она содержит код, имеющий доступ к AD и способный разрешить использование (снять блокировку) с этой учетной записи.

Детали ASP кода

Сценарий Enable.asp содержит код, который используется страницей Migration Complete для активации учетной записи вновь мигрировавшего пользователя. На листинге 2 представлена часть этого сценария. Код фрагмета A позволяет вам определить семь переменных для учетных записей, которые вы хотите активировать. Первая переменная - это sLDAPServer, содержит имя контролера AD (DC). Этот сценарий использует авторизационные запросы к Lightweight Directory Access Protocol (LDAP), чтобы этот сервер разрешил использование данной учетной записи. Следующие две переменные sObjAccess и sObjKey содержат, соответственно, имя и пароль учетной записи, под которой сценарий будет регистрироваться на контроллере домена.

Как вы знаете, AD позволяет вам создавать контейнеры, называемые organizational units (OU), которые могут содержать объекты пользовательских учетных записей. Когда я переносил учетные записи, я предпочел разместить новые учетные записи в OU с именем Staging. Когда учетная запись была готова к использованию, я активировал соответствующие записи и перемещал их в Users OU, либо OU, заданное администраторами этих учетных записей. Переменные sStagingOU и sDestinationOU определяли эти контейнеры. После того, как Enable.asp активировал учетную запись, сценарий премещал эту запись из Staging OU в заданное OU (в нашем примере это OU Users ). С точки зрения администрирования, такой подход удобен, поскольку после миграции какая-либо учетная запись, оставшаяся в Staging OU, возможно, не используется и может быть удалена. С точки зрения обеспечения безопасности я предпочел такой метод миграции, поскольку сценарий отрабатывался только один раз во время активации учетной записи. Такое решение предотвращает случай, когда кто-либо, используя сценарий (или учетную запись LDAP) после миграции будет пытаться активировать специально заблокированную учетную запись.

Последние две переменные, необходимые вам, называются sOldDomain и sNewDomain. Переменная sOldDomain содержит имя домена NT 4.0. Когда кто-либо открывает Web страницу, сценарий восстанавливает ID пользователя из серверной переменной AUTH_USER, как это показано во фрагменте B. ID состоит из двух частей, ID домена и ID пользователя в формате DOMAINUSERID. Сценарий сравнивает имя домена с содержимым переменной sOldDomain. Когда эти величины совпадают, сценарий продолжает выполняться, иначе работа сценария прерывается. Переменная sNewDomain используется сценарием для отображения нового домена пользователя и USER ID на Web-странице, выводимой пользователю (вид страницы показан на рисунке 1).

Порядок работы сценария прост. Сценарий получает текущий домен регистрации и имя учётной записи из Internet Explorer и использует эту информацию для построения LDAP путей к различным контейнерам AD. Затем, как показано в коде фрагмента C, сценарий использует имя учетной записи и пароль, определённые в переменных sObjAccess и sObjKey для установления авторизованной сессии с LDAP и доступа к объектам,. представляющим пользовательские учетные записи. После изменения статуса объекта на разрешенный к использованию (enabled), сценарий использует метод SetInfo этого объекта для передачи изменений в AD.

Затем, сценарий, используя авторизованный вызов к LDAP, создает объект, ссылающийся на целевое (т.е. пользовательское) OU, как это видно из кода фрагмента D. Затем программа вызывает метод MoveHere объекта, который перемещает учетную запись в её постоянное место. В статье далее сценарий использует оператор response.write для генерации Web - страницы, выводящей отчет об успехе или ошибках в работе сценария.

В фрагментах C и D используется оператор err.number . После каждой операции обращения и манипуляций с AD, сценарий тестирует код ошибки . Когда код ошибки не выдается, сценарий переходит к следующему шагу.

Настройки в AD

Перед использованием сценария вам для начала необходимо настроить соответствующую учетную запись в AD, OU, и дать необходимые права. Чтобы сделать это, откройте оснастку Active Directory Users and Computers консоли Microsoft Management Console (MMC), щелкните правой кнопкой на контейнере Users, выберите New, User из контекстного меню. Задайте имя учетной записи, например Migration- Enabler в поле User Logon Name . Для сохранения порядка, заполните поля Full Name и User Logon Name, затем нажмите Next. Введите и подтвердите пароль, отметьте пункт Password Never Expires (Пароль никогда н6е истекает), нажмите Next, затем нажмите Finish.

Для создания OU Staging, правой кнопкой выберите имя домена верхнего уровня и выберите New, Organizational Unit из контекстного меню. Задайте имя OU Staging и нажмите OK. Затем вам надо дать административные права сервисной учетной записи так, чтобы она могла изменять объекты учетных записей, которые будут находиться в этом OU. Нажмите правую кнопку на вновь созданном OU Staging OU и выберите Delegate Control (Делегировать управление). Когда откроется мастер Delegation of Control Wizard, нажмите Next для начала операции. На странице Users or Groups мастера, нажмите Add и наберите имя сервисной учетной записи (например, Migration- Enabler). Нажмите Check Names для подтверждения правильности ввода, нажмите OK, затем нажмите Next. На странице мастера Tasks to Delegate (Задачи для делегирования), выберите Create a Custom Task to Delegate (Создать задачу для делегирования) и нажмите Next. На странице Active Directory Object Type (Тип Adобъекта), выберите Only the following objects in the folder (Только эти объекты в папке). Пролистайте список объектов и отметьте объекты типа User objects, затем выберите опцию Delete selected objects in this folder, затем нажмите Next. Когда откроется страница Permissions, выберите Read All Properties и Write All Properties, как показано на Рисунке 2. Нажмите Next, затем Finish.

Затем вам необходимо делегировать доступ к контейнеру Users . Правой кнопкой щеклните на контейнере Users и выберите Delegate Control. Повторите аналогичные шаги по делегированию прав для OU Staging . Однако теперь, на странице мастера Delegation of Control Wizard странице Active Directory Object Type, вместо выбора Delete selected objects in this folder (Удалить выбранные объекты в этой папке ), выберите Create selected objects in this folder (Создать выбранные объекты в этой папке), как показано на рисунке 3. Вам необходимо гарантировать права на удаление в OU Staging и гарантировать права на создание объектов в OU Users, поскольку сценарий перемещает учетные записи объектов из одного OU в другое. AD выполняет перемещение путем удаления объектов в одном контейнере и создания их в другом.

Настройка IIS

Перед запуском сценария, вам необходимо настроить Microsoft Internet Information Services (IIS) 5.0 или более позднюю версию этого продукта. Вам необходимо создать виртуальный каталог, содержащий Enable.asp и настроить права на этот каталог так, чтобы в него не разрешался анонимный доступ. Зарегистрируйтесь на вашем IIS с учетной записью, имеющей права локального администратора и запустите оснастку MMC Internet Information Services Manager. Раскройте дерево контейнера до того уровня, пока вы не увидите Default Web Site и нажмите на него правой кнопкой мыши. Выберите New, Virtual Directory. Когда запустится мастер New Virtual Directory Wizard, напишите Next для начала настройки. На странице мастера Virtual Directory Alias введите имя Migration и нажмите Next. На странице Website Content Directory (Каталог содержимого сайта) нажмите Browse и выберите папку Inetpub. Нажмите Make New Folder и введите Migration в качестве имени папки. Нажмите OK для закрытия обозревателя папок и затем Next для перехода на следующую страницу. Выберите пункт Run scripts (such as ASP) и очистите все остальные флажки. Нажмите Next и Finish для создания виртуального каталога Migration и выберите Properties. Выберите закладку Directory Security и нажмите Edit в секции Authentication and Access Control (Авторизация и права доступа) На странице Authentication Methods Properties (свойства методов аутентификации), очистите флажок Enable anonymous access (разрешить анонимный доступ) и установите флажок Integrated Windows Authentication. Нажмите OK дважды для выхода из страницы свойств виртуального каталога.

Следующее, что вам необходимо сделать, это поместить Enable.asp (листинг 3) в папку InetpubMigration и поменять значения семи переменных в коде фрагмента A и задать их значения в соответствии с вашей конфигурацией. Чтобы протестировать сценарий, создайте заблокированную учетную запись в OU Staging и присвойте ей то же самое имя, что и в домене Windows NT 4.0 . Зарегистрируйтесь под учетной записью из домена NT 4.0 и зайдите на ASP Web - страницу, введя адрес http://yourIISserver.domain.com/ migration/enable.asp, где yourIISserver - имя вашего IIS-сервера. Если вы осуществили все настройки правильно, вы получите подтверждение, подобное показанному на Рисунке 1. Вы можете воспользоваться оснасткой Active Directory Users and Computers для проверки того, что учетная запись активирована и перемещена в OU Users .

Мощный инструмент

Миграция никогда не бывает беспроблемной. В дополнение к массиву стандартных задач, которые порождает процесс миграции, у вас появляется дополнительная сложная работа по координации и согласованию операций, таких как копирование профилей на все компьютеры предприятия для большого количества пользователей. Вы можете упростить себе жизнь, воспользовавшись возможностями сценариев так, что пользователи сами помогут вам в решении некоторых задач.


Листинг 1. Sample Profile Migration Batch File
@echo off
update.exe %COMPUTERNAME% -y -m MAP.USR
 iexplore.exe http://intranet/migration/enable.asp
 

Листинг 2. Enable.asp Excerpt
? начало фрагмента A
sLDAPServer = ?dc.domain.com?
sObjAccess = ?ADdomainServiceAccount?
sObjKey = ?Service!Password?
sStagingOU = ?OU=Staging,DC=domain,DC=com?
sDestinationOU = ?CN=Users,DC=domain,DC=com?
sOldDomain = ?NT4DOM?
sNewDomain = ?ADDOM?
? конец фрагмента A
начало фрагмента B
начало комментария
? Get the ID of the user accessing
 the page and store it in an array.
? Получение ID пользователя,
 обращающегося к странице и сохранение
?его в массиве.
конец комментария
aUserInfo = split(Request.ServerVariables(?AUTH_USER?),??)
начало комментария
? Get the domain portion.
? Получение имени домена.
конец комментария
sDOM = ucase(aUserInfo(0))
начало комментария
? Get the ID portion.
? Получение ID пользователя.
конец комментария
sLAN = ucase(aUserInfo(1))
If sDOM = sOldDomain Then
response.write ?? _
 & ? ? _
 & ?MIGRATION COMPLETE
?
начало комментария
? Build distinguished name (DN) in the 
? format cn=object,ou=container,dc=domain.
? Построение абсолютного имени (DN) в формате 
? cn=object,ou=container,dc=domain.
конец комментария
sTargetAccount = ?cn=? & sLAN &
 ?,? & sStagingOU
начало комментария
? Build LDAP strings. Examples:
? Построение строк LDAP . Примеры:
? LDAP://dc.neulan.net/OU=staging,DC=neulan,DC=net
? LDAP://dc.neulan.net/CN=Users,DC=neulan,DC=net
конец комментария
sObjectRef = ?LDAP://? & sLDAPServer
 & ?/? & sTargetAccount
sDestinationOU = ?LDAP://? & sLDAPServer
 & ?/? & sDestinationOU
? конец фрагмента B
? начало фрагмента C
On Error Resume Next
Set adsRoot = GetObject(?LDAP:?)
начало комментария
? Open authenticated access to AD.
? Открытие авторизованного доступа к AD.
конец комментария
If err.number = 0 Then
Set objUser = _
adsRoot.OpenDSObject(sObjectRef,sObjAccess,sObjKey,0)
начало комментария
? Enable the account.
? Активация учетной записи.
конец комментария
If err.number = 0 Then
objUser.AccountDisabled = false
начало комментария
? Write the information to AD.
? Запись информации в AD.
конец комментария
objUser.SetInfo
? конец фрагмента C
? начало фрагмента D
начало комментария
? Get Users OU.
? Получение OU пользователя.
конец комментария
If err.number = 0 Then
Set objDestOU = adsRoot.OpenDSObject _
(sDestinationOU,sObjAccess,sObjKey,0)
начало комментария
? Move user from Staging OU to Users OU.
? Перемещение пользователя из OU Staging в OU Users.
конец комментария
If err.number = 0 Then
objDestOU.MoveHere ?LDAP://? & _
sTargetAccount, vbNullString
? конец фрагмента D

Листинг 3. Сценарий Enable.asp



<%
' начало фрагмента 1 sLDAPServer = "dc.domain.com"
sObjAccess = "ADdomainServiceAccount" sObjKey = "Service!Password" ' case sensitive
sStagingOU = "OU=staging,DC=domain,DC=com" sDestinationOU = "CN=Users,DC=domain,DC=com"
sOldDomain = "NT4DOM" ' must be UPPERCASE sNewDomain = "ADDOM" ' must be UPPERCASE
' конец фрагмента 1
' начало фрагмента 2 ' Get the ID of the user accessing the page and store in array aUserInfo = split(Request.ServerVariables ("AUTH_USER"),"")
sDOM = ucase(aUserInfo(0)) ' Get Domain Part sLAN = ucase(aUserInfo(1)) ' Get ID Part
if sDOM = sOldDomain Then ' Only do this if its the corrent old Domain response.write "  MIGRATION COMPLETE
"
sTargetAccount = "cn=" & sLAN & "," & sStagingOU ' Build Distinguished Name ' in the format cn=object,ou=container,dc=domain
sObjectRef = "LDAP://" & sLDAPServer & "/" & sTargetAccount ' Make LDAP strings sDestinationOU = "LDAP://" & sLDAPServer & "/" & sDestinationOU ' examples LDAP://dc.neulan.net/OU=staging,DC=neulan,DC=net ' examples LDAP://dc.neulan.net/CN=Users,DC=neulan,DC=net ' конец фрагмента 2
' начало фрагмента 3 on error resume next Set adsRoot = GetObject("LDAP:") if err.number = 0 then Set objUser = adsRoot.OpenDSObject (sObjectRef,sObjAccess,sObjKey,0) ' Open authenticated access to AD if err.number = 0 then objUser.AccountDisabled = false ' Enables the Account objUser.SetInfo ' Stores the information Back to AD ' конец фрагмента 3
' начало фрагмента 4 if err.number = 0 then Set objDestOU = adsRoot.OpenDSObject (sDestinationOU,sObjAccess,sObjKey,0) ' Get Accounts OU if err.number = 0 Then objDestOU.MoveHere "LDAP://" & sTargetAccount, vbNullString ' Move User from Staging OU ' конец фрагмента 4
' начало фрагмента 5 if err.number = 0 Then Response.write "P
" Response.write "Your " & snewDomain& "" & sLAN & " account has been enabled.

" Response.write "It takes 15 to 30 minutes to become active in the system.
" Response.write "Please wait at least 15 minutes to log on." else Response.write "N
" Response.write "There was a problem enabling your " & snewDomain& "" & sLAN Response.write " account.
Please contact the helpdesk
" Response.write "Problem moving account to " & sDestinationOU & "
" Response.write "Error Code: " & err.description & " (" & err.number & ") " end if else Response.write "N
" Response.write "There was a problem enabling your " & snewDomain& "" & sLAN Response.write " account.
Please contact the helpdesk
" Response.write "Problem getting to the OU: " & sDestinationOU & "
" Response.write "Error Code: " & err.description & " (" & err.number & ") " end if else Response.write "N
" Response.write "There was a problem enabling your " & snewDomain& "" & sLAN Response.write " account.
Please contact the helpdesk
" Response.write "Error Code: " & err.description & " (" & err.number & ") " end if else Response.write "N
" Response.write "There was a problem enabling
your " & snewDomain& "" & sLAN Response.write " account.
Please contact the helpdesk

" Response.write "Your account was not found in:
" & sStagingOU Response.write "
This can happen if you have already enabled your account." end if else Response.write "N
" Response.write "There was a problem enabling your " & snewDomain& "" & sLAN Response.write " account.
Please contact the helpdesk
" Response.write "Error Code: " & err.number & " (Error communicating with Domain Controller)" end if else Response.write "N
" Response.write "You are not logged in from the correct account domain.
" Response.Write Request.ServerVariables("AUTH_USER") & "
" Response.write "Please contact the helpdesk
" End If ' конец фрагмента 5
set objDestOU = Nothing ' Destroy object and give Back the memory set objUser = nothing ' Destroy object and give Back the memory set adsRoot = nothing ' Destroy object and give Back the memory

%>