Многие системные администраторы Windows 2000 и Windows NT убедились, что разработка обычных сценариев для управления инфраструктурой принципиально отличается от использования традиционных графических инструментальных средств. Тем, кто придерживается такой точки зрения, я советую изучить технологию Windows Script (WS) и сопутствующие ей, в частности Active Directory Service Interfaces (ADSI). Писать пользовательские сценарии для управления средой не требуется, а создавать сценарии для Active Directory (AD), позволяющие осуществлять администрирование, становится намного проще. В этой статье я расскажу о трех основных интерфейсах в ADSI (IADsOpenDSObject, IADs и IADsContainer) и покажу, каким образом, используя эти основные интерфейсы, можно выполнить более 80% обычных задач управления AD.

Что такое ADSI?

Интерфейс ADSI — это набор COM-объектов для программирования, которые позволяют единообразно манипулировать многочисленными гетерогенными каталогами. Интерфейс ADSI — это основной программный интерфейс к AD, разработанный Microsoft, его используют все графические средства управления AD.

Изначально ADSI поддерживал протоколы Lightweight Directory Access Protocol version 3 (LDAPv3), NT 4.0 SAM, Novell Directory Services (NDS) и NetWare Bindery. Поскольку ADSI поддерживает LDAP, он может использоваться для управления каталогами, основанными на LDAP/X.500, включая Windows 2000 AD, Microsoft Exchange Server 5.5 и Site Server 3.0. Хотя я буду рассматривать именно AD, многие принципы, обсуждаемые в этой статье, применимы и к другим каталогам.

Так как интерфейс ADSI предназначен для программирования, его можно применять для написания сценариев управления каталогом в любой COM-совместимой среде, включая Windows Script Host (WSH), VBScript, JScript и ActivePerl. Интерфейс ADSI также поддерживает быстродействующие, только для чтения, запросы ActiveX Data Objects (ADO) через OLE DB.

ADSI устанавливает интерфейсы на стороне клиента. Это означает, что инсталлировать его нужно только на тот компьютер, который запускает сценарии. Дополнительно устанавливать ADSI на целевые контроллеры домена не требуется. Система Win-dows 2000 включает ADSI, но если планируется запускать сценарии ADSI на компьютерах с Windows NT или Windows 9x, то его необходимо загрузить и установить. ADSI 2.5 — это текущая версия, которую можно загрузить с Web-сайта Microsoft по ADSI (http://www.microsoft.com/adsi). На сайте также размещены связанные с ADSI официальные документы и средства для разработчиков, например набор инструментальных средств разработки для ADSI (SDK).

Терминология AD и ADSI

Чтобы эффективно использовать ADSI, необходимо изучить терминологию сценариев AD.

AD — это служба каталогов (DS) Win-dows 2000. DS — сетевая служба, которая идентифицирует и хранит информацию обо всех сетевых ресурсах и обеспечивает пользователям и приложениям доступ к ней. Служба каталогов AD — это распределенный иерархический тиражируемый каталог информации (Distributed information tree, DIT), который хранится в каталоге \%systemroot% tds на всех контроллерах домена Windows 2000 в фaйле ntds.dit. Можно обновить любую копию AD, и изменения AD будут тиражироваться на все контроллеры домена.

Служба каталогов AD в чем-то сходна с базой данных (например, AD тоже хранит информацию). Однако, в отличие от реляционных баз данных, которые предназначены для выполнения операций вставки, обновления и удаления, AD — это иерархическая структура, оптимизированная для операций чтения.

Каждый контроллер домена Windows 2000 поддерживает доступную для записи копию каталога (реплику), и каждая реплика состоит как минимум из трех разделов (известных как контексты именования): контекста именования по умолчанию, контекста именования схемы и контекста именования конфигурации. Контекст именования по умолчанию хранит информацию об общих объектах домена (таких, как компьютеры, группы, организационные единицы (OU), пользователи). Контекст именования схемы хранит схему AD (которая будет описана ниже), а контекст именования конфигурации хранит информацию о конфигурации узла и подсети. Основные интерфейсы обеспечивают общий и постоянный доступ к управляемым объектам во всех трех контекстах именования.

Компонент «схема» — это коллекция описаний классов и атрибутов; она определяет, какую информацию может хранить AD. Класс подобен шаблону для объекта, а атрибут — это свойство объекта (например, общее имя, описание, отличительное имя (DN)). Схема описывает обязательные и дополнительные атрибуты объекта. В рамках ADSI-сценариев можно получить доступ к схеме для установки обязательных и дополнительных свойств объектов. Кроме того, схема определяет структуру дерева каталога DIT. Объекты, которые могут содержать другие объекты, называются контейнерами; объекты, которые не могут содержать другие объекты, называются листьями.

Служба каталогов AD представляет сетевые ресурсы как объекты. С точки зрения AD объект есть заданный именованный набор свойств и связанных с ними значений, которые представляют конкретные сетевые ресурсы (например, компьютер, названный US-E-FN-01; группа, имеющая имя Investors, организационное подразделение OU с именем Finance, пользователь Джуди). С точки зрения программы или сценария объект есть экземпляр класса схемы.

Интерфейсы в ADSI являются механизмами, которые используются для модификации свойств объектов. Термин «интерфейс» — не единственный в ADSI. В программировании COM-интерфейс — это набор методов и свойств, которые предоставляет COM-объект. Методы оказывают некоторое воздействие на объект, а свойства характеризуют состояние объекта. Объекты COM могут предоставлять разнообразные интерфейсы. Например, ADSI обеспечивает более 50 интерфейсов. Однако всего три базовых интерфейса позволят выполнить многие задачи в AD.

Таким образом, ADSI — это набор программных интерфейсов, который используется для управления объектами AD. Интерфейсы ADSI обеспечивают методы и свойства для создания, удаления и модификации объектов. Объект есть набор свойств, которые представляет сетевой ресурс. Описание класса объекта, которое хранит схема, определяет свойства, создающие объект. Схема класса определяет обязательные и дополнительные атрибуты объекта. Сценарий ADSI использует методы ADSI для создания и удаления объектов и модификации свойств.

Каждый объект в AD имеет несколько имен. Отличительное имя DN и относительное отличительное имя (RDN) являются основными в соглашении об именовании для обращения к объектам из сценариев ADSI. Имя DN определяет точное расположение объекта в дереве DIT, основанном на именах атрибутов. Имя RDN — это обязательный атрибут «имя» объекта. Соотношение между именами DN и RDN в AD подобно соотношению между полностью определенным путем к файлу и именем файла в файловой системе.

Каждый DN-компонент есть RDN, а каждый RDN есть строка, состоящая из двух частей (параметр и значение), которая изображается как «key=va-lue». Key идентифицирует реальный тип атрибута, а value является значением атрибута.

В документе Internet Engineering Task Force (IETF) Request for Comments (RFC) 2253, «Lightweight Directory Access Protocol (v.3): UTF-8 String Representation of Distinguished Na-mes», описаны параметры и типы атрибутов, которые используются для создания имен DN в LDAPv3. В Таблице 1 перечислены некоторые из обычно применяемых параметров и соответствующие типы атрибутов.

Приведу пример связи между DN и RDN. На Рисунке 1 показаны DN и RDN для пользователя Джуди Шнайдер. RDN для Джуди — это «cn=Judy Schneider»; cn — это параметр для общего имени атрибута, а строка «Judy Schneider» является значением. Мы можем проверить имя DN Джуди, чтобы определить его точное месторасположение в DIT. Джуди входит в подразделение Finance OU, а то, в свою очередь, относится к домену acme.com. Можно представить DN как комбинацию всех объектов RDN при перемещении от объекта к корню дерева.

Рисунок 1. Имена DN и RDN.

Имя DN объекта должно быть уникальным во всем каталоге, а RDN объекта должно быть уникальным в текущем контейнере. Параметр и знак равенства — это обязательные компоненты RDN. Типы объектов, которые не имеют конкретного параметра, используют по умолчанию общее имя параметра «cn=».

Общие задачи AD

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

Процесс написания любого ADSI-сценария включает несколько основных этапов. В следующем сценарии я перечислил действия, необходимые для создания объекта «пользователь» и управления им.

Компания Acme Widgets приглашает Джуди Шнайдер на работу в качестве инспектора. Джуди будет работать в финансовом подразделении компании — Finance OU. Вместе с системным администратором Acme Widgets совершим четыре шага для создания нового пользователя.

  1. Используя функцию GetObject VBScript, подсоединимся к целевому контейнеру («ou=Finance» в этом примере), который будет содержать нового пользователя.
  2. Используя метод Create из ADSI, создадим новый объект «пользователь» в локальном кэше свойств. Интерфейс IADsContainer предоставляет метод Create.
  3. Используя методы Put и PutEx из ADSI, установим обязательные и дополнительные свойства объекта «новый пользователь». Интерфейс IADs обеспечивает методы Put и PutEx.
  4. С помощью метода SetInfo из ADSI запишем новый объект в каталог. SetInfo также является частью интерфейса IADs.

    Джуди покупает новый дом и переезжает. Необходимо обновить ее домашний адрес и номер домашнего телефона, поэтому выполняем следующие действия.

  5. Используя функцию GetObject из VBScript, подсоединимся к целевому объекту («cn=Judy Schneider»), свойства которого нужно изменить.
  6. Используя методы из IADs — GetInfo, GetInfoEx, Get или GetEx — на выбор, инициализируем локальный кэш свойств объекта.
  7. Используя метод Put или PutEx, обновим свойства в локальном кэше свойств.
  8. Используя SetInfo, зафиксируем изменения в каталоге.

    Джуди выдвигается на пост финансового директора компании (CFO). Необходимо перевести Джуди из финансового подразделения (Finance OU) в руководство (Executive OU), для этого выполняем два шага.

  9. Подключаемся к целевому контейнеру («ou=Executive») пользователя, которого требуется переместить.
  10. Используя метод MoveHere, перемещаем соответствующий объект пользователя. Интерфейс LADsCon-tainer предоставляет метод MoveHere.

    Джуди переходит к конкуренту. Необходимо удалить объект пользователя, поэтому выполним два последних шага.

  11. Используя функцию GetObject из VBScript, подключаемся к целевому контейнеру («ou=Executive»), который содержит объект пользователя.
  12. С помощью метода Delete из ADSI удаляем объект пользователя. Интерфейс IADsContainer предоставляет метод Delete.

В этом примере показаны основные шаги, которые являются общими для большинства сценариев ADSI. Приступая к выполнению каждой задачи, нужно подключиться к объекту. После подключения к объекту используются методы, содержащиеся в двух основных интерфейсах IADs и IADs-Container, с помощью которых и происходит управление жизненным циклом объекта.

Эти основные шаги можно применять и к другим объектам в каталоге. Для этого нужно отвлечься от основных интерфейсов в ADSI и выполнить перечисленные шаги в сценарии на базе функций. Я использую easyadsi.vbs в качестве примера и исследую основной интерфейс IADsOpenDSObject. В Листинге 1 показана часть сценария, которая выполняет первые четыре шага для создания нового объекта пользователя. Полностью листинг можно загрузить с Web-сайта Win-dows 2000 Magazine по адресу: http://www.win2000mag.com/. (Введите 9168 в текстовом окне InstantDoc ID и загрузите файл 9168.zip.)

Листинг 1. Файл Easyadsi.vbs.

Подключение к AD

Подключение — это первый шаг для взаимодействия с AD; соединение с объектом в LDAP называют запросом на привязку (bind request). Привязка — это точка в сценарии ADSI, в которой происходит процесс аутентификации. Внутренние LDAP-провайдеры интерфейса ADSI (adsldp.dll и wldap32.dll) создают и возвращают ссылку на указанный объект (например, домен, OU, группа, пользователь, принтер, служба, совместно используемый ресурс, сайт, класс схемы).

Используем функцию GetObject из VBScript для привязывания к объекту AD. Строка, передаваемая в Get-Object, — это ADSI LDAP — путь, который идентифицирует целевой объект. Для связывания с объектом можно использовать несколько подходов, которые основаны на синтаксисе LDAP-пути. ADSI LDAP-путь необходимо начать с «LDAP:». Далее может следовать строка с дополнительными элементами, как показано в примере на Рисунке 2.

Обязательный префикс «LDAP:» — это программный идентификатор (ProgID) для провайдера LDAP в ADSI. Идентификатор ADSI ProgIDs определяет ADSI провайдера DLL, через который сценарий поддерживает связь с каталогом. Идентификатор ADSI ProgIDs является чувствительным к регистру, поэтому для префикса «LDAP:» необходимо всегда использовать заглавные буквы. Остаток ADSI LDAP-пути нечувствителен к регистру.

Дополнительные элементы LDAP-пути включают имя целевого сервера, IP-адрес, номер порта LDAP и DN. Элементы, добавляемые к префиксу «LDAP:», определяют, как ADSI привязывается к AD.

Серверные привязки создаются при добавлении имени целевого сервера или IP-адреса как части LDAP-пути, что показано в примерах на Рисунке 3. Следует избегать привязок с явным указанием имени сервера или IP-адреса, потому что сценарий выдаст ошибку, если сервер окажется отключенным. Можно установить номер порта LDAP, если DS прослушивает другой порт, а не порт LDAP по умолчанию (порт 389). Однако не нужно беспокоиться о прослушивании AD по другому порту, потому что контроллеры домена Windows 2000 резервируют порт 389 для AD. Запросы без привязки к серверу удаляют зависимость, связанную с LDAP-путями, которые содержат явно указанные имена серверов. Поэтому целесообразнее использовать пути без имени сервера. Если не указать имя целевого сервера или его IP-адрес, ADSI выдает запрос к новому Win32 API (DSGetDCNa-me), который запрашивает DNS для поиска контроллера в домене, где зарегистрировался данный пользователь. Интерфейс ADSI пытается определить местоположение контроллера домена и подключиться к нему в локальном узле рабочей станции, основываясь на IP подсети. Если ADSI не может определить контроллер домена в узле, он использует первый ответивший сервер каталога.

Пути LDAP без указания сервера обычно включают имя DN, которое идентифицирует целевой объект. В запросе на привязку, показанном в Листинге 1 под меткой А, я сделал привязку к Finance OU, которая находится в домене acme.com. Строковое значение в переменной strContainer указывает его местоположение.

На Рисунке 4 показаны запросы на привязку, которые содержат другие виды путей LDAP без указания сервера. В первом примере на Рисунке 4 я выполнил привязку точно к de-faultNamingContext (где находятся объекты «пользователь», «компьютер», «группа» и OU) из домена acme.com. Во втором примере я сделал привязку к объекту конкретного пользователя. Третий пример является запросом на привязку без указания DN. При таком типе запроса ADSI создает привязку к специальному LDAPv3-объекту, Root Directory Ser-vice Entry (rootDSE), и использует свойство defaultNamingContext объекта rootDSE для привязки к корню DIT. Результат такой же, как и в первом примере, но использование запроса без указания DN снимает зависимость от специфики домена.

Можно также явно сделать привязку к объекту rootDSE. Введенный в версии LDAPv3 rootDSE находится на вершине дерева DIT каждого контроллера домена. В отличие от принципа привязки без DN (например «LDAP:»), в котором rootDSE возвращает только имя DN для defaultNamingContext, привязка напрямую к rootDSE позволяет получить доступ ко всей информации о каталоге сервера, предоставившего объект rootDSE. В этой информации будут и имена DN для всех контекстов именования каталога. Как показано в Листинге 2, я использовал свойства defaultNa-mingContext, schemaNa-mingContext и configura-tionNamingContext объекта rootDSE, отмеченные как A, B и C, для привязки к корню каждого контекста именования каталога и просмотра высокоуровневых объектов.

Листинг 2. Файл RootDSE.vbs.

До сих пор я надеялся на имеющиеся у меня разрешения при проверке запроса на привязку. Хотя такой метод аутентификации достаточно эффективен, в некоторых случаях бывает необходимо указать другие учетные данные или соответствующий тип аутентификации. Интерфейс IADSOpenDSOb-ject из ADSI предоставляет для выполнения привязки к объекту метод OpenDSObject, который предполагает использование указанных пользователем учетных данных. Метод Open-DSObject допускает четыре параметра, которые перечислены в Таблице 2.

В Листинге 1 показано, как использовать OpenDSObject вместо текущих учетных данных пользователя (метка B). Замените код с меткой A в Листинге 1 кодом с меткой B в Листинге 1 для использования Open-DSObject. Перед тем как обратиться к Open-DSObject, нужно ввести

Set oRoot=GetObject («LDAP:»)

чтобы получить ссылку на провайдера LDAP. В качестве имени пользователя можно указать DN, User Principal Name (UPN), низкоуровневое учетное имя SAM (pre-Windows 2000) или Anonymous.

Советы по привязкам

Интерфейс ADSI обеспечивает большую гибкость при выполнении привязок к объектам AD. При разработке собственных ADSI-сценариев нужно иметь в виду следующее.

  1. Используйте текущие учетные данные всегда, когда это возможно.
  2. Никогда не применяйте явно указанные пароли в своих сценариях. При необходимости использовать пароль нужно создать запрос, адресованный пользователю, или извлечь пароль из системы безопасности. Затем следует сохранить его во временной переменной и уничтожить содержимое переменной сразу же после запроса на привязку.
  3. Используйте rootDSE, когда сценарий делает привязку к корню текущего домена.
  4. Избегайте явного указания имен серверов в путях LDAP.
  5. Делайте привязки к контейнерам для создания, перемещения и удаления объектов в контейнере.
  6. Делайте привязки к объектам-листьям для модификации свойств объекта.

В следующей статье, посвященной ADSI, я планирую рассказать о двух других основных интерфейсах ADSI — IADs и IADsContainer. А пока рекомендую читателям попробовать привязаться к некоторым объектам в своем каталоге. Для большего эффекта советую включить Network Monitor и попытаться задействовать несколько методов привязки.

БОБ УЭЛЛС - консультант по программному обеспечению; специализируется на вопросах проектирования и реализации инфраструктуры информационных систем, основанных на NT. Имеет сертификаты MCSE и MCT. С ним можно связаться по адресу: bobwells@win2000mag.com.


Таблица 1. LDAPv3 DNs.
KeyAttribute Type
CNcommonName
LlocalityName
STstateOrProvinceName
OorganizationName
OUorganizationalUnitName
CcountryName
STREETstreetAddress
DCdomainComponent
UIDuserid