На главную страницу
 
  Главная 
  Новости 
  Статьи  RSS
  Программное обеспечение 
  Форум 
  Опросы 
  Полезные ссылки 
MSExchange.ru ISADocs.ru WinSecurity.ru NetDocs.ru

Exchange 5.5
Exchange 2000
Exchange 2003
Exchange 2007
Общее
Exchange 2010

Поиск по сайту


Авторизация

Запомнить меня на этом компьютере
  Забыли свой пароль?
  Регистрация

Подписка

Изменение параметров

Статистика

Hits 2748748
13441
Hosts 1649570
478
Visitors 229675
554

12
Мониторинг активности принтеров

Главная / Статьи / Exchange 2003 / Разработка скриптов для Exchange с использованием VBScript и ADSI (Часть 1)


SurfCop

Разработка скриптов для Exchange с использованием VBScript и ADSI (Часть 1)

Версия для печати Версия для печати

Эта статья переведена силами и средствами компании Red Line Software. Размещение данного переведенного материала на других сайтах без разрешения компании Red Line Software запрещается.

В этой статье я покажу вам основы написания скриптов на языке VBScript, используя ADSI интерфейс предоставляемый службой Active Directory для хранения и получения информации Exchange сервера.

Читайте:

Введение

Скрипты могут быть мощным инструментом. В Интернете имеется много хорошо написанных скриптов, которые могут быть полезными. Изменения, которые отвечают вашим потребностям сделать не трудно, но написать свои скрипты и заставить скрипты работать лучше для ваших потребностей требует некоторых знаний внутренних механизмов работы Active Directory и конечно, языка на котором пишутся скрипты.

Эта статья представит несколько основных методов написания скриптов. Я объясню в деталях и логику скриптов предоставленных VBScript, и логику интерфейсов предоставленных Active Directory.

Доступ к объектам Active Directory

Exchange сервер 2000/3 хранит свои объекты в Active Directory. Чтобы иметь возможность получить доступ к пользователям, контактной и групповой информации вы должны быть знакомы со способом хранения объектов и с нотацией LDAP (протокол службы каталогов) который используется для доступа к этим объектам.

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

Dim MyUser
Dim HomeServer

Set MyUser = GetObject ("LDAP://CN=Administrator,CN=Users,DC=sunnydale,DC=muni")
HomeServer = myUser.Get("msExchHomeServerName")
WScript.Echo "HomeServer is" & HomeServer

Скрипт начинается с объявления двух переменных. В VBScript, не так как в VB6, переменные не имеют типа до тех пор пока им не присвоят значение. Фактически две первые строки являются лишними, так как вы не обязаны декларировать переменные в VBScript. Тем не менее, это делает скрипт более читаемым если вы декларируете их и считается хорошим стилем программирования.

Затем устанавливается значение переменной MyUser как указатель на объект Active Directory, в этом случае на учетную запись администратора, которая расположена в контейнерах пользователей в домене. Чтобы отличать указатели от других типов переменных используется ключевое слово «Set». Заметьте, что переменной HomeServer в следующей строке присваивается значение свойства пользователя. Тем не менее, это не указатель, так как нет ключевого слова «Set». Суммируя все это можно сказать, что переменная MyUser указывает на объект Active Directory где информация хранится на самом деле, тогда как переменная HomeServer это строковая переменная которая содержит информацию, полученную из Active Directory.

Функция GetObject используется для получения указателя на объекты Active Directory, используя LDAP нотацию. Имеется три типа объектов:

CN = Контейнеры, пользователи, контакты, группы и другие объекты которые обычно не имеют дочерних объектов.
OU = Организационные модули которые содержат такие объекты как пользователи, контакты, группы и др.
DC = Доменные контейнеры, которые создаются отделением полного внутреннего доменного имени (в этом примере, sunnydale.muni)

Вы можете видеть структуру Active Directory LDAP, установив Windows 2000/3 Support Tools и запустив ADSIEdit.

Эта версия скрипта так же будет работать:

Set MyUser = GetObject ("LDAP://CN=Administrator,CN=Users,DC=sunnydale,DC=muni")
HomeServer = myUser.msExchHomeServerName
WScript.Echo "HomeServer is" & HomeServer

Заметьте, что не требуется использовать функцию «Get», чтобы получить значение свойства объекта, но вы можете встретить скрипты, в которых она используется для того же.

Скрипт опрашивает первый контроллер домена, который он находит. Если вам необходимо найти свойство, которое существует только у глобального каталога сервера (GC) вам следует сделать так, что бы все ваши контроллеры доменов являлись глобальными каталогами серверов или чтобы вы специфицировали глобальный каталог таким образом:

Set MyUser = GetObject ("LDAP://GCName /CN=Administrator,CN=Users,DC=sunnydale,DC=muni")

Вы можете также опросить только глобальный каталог (GC) используя GC:// нотация как следует:

Set MyUser = GetObject ("GC://GCName /CN=Administrator,CN=Users,DC=sunnydale,DC=muni")

Вы можете также установить свойства объекта

Set MyUser = GetObject ("LDAP://CN=Administrator,CN=Users,DC=sunnydale,DC=muni")
MyUser.msExchHideFromAddressLists = True
MyUser.SetInfo

Когда вы изменяете свойства объекта, изменения кэшируются, не применяются сразу. Подпрограмма SetInfo пытается записать измененные атрибуты в объект. Конечно, Active Directory имеет все виды проверок, чтобы определить правильные ли атрибуты, если нет, то VBScript генерирует ошибку.

Работа с коллекциями

VBScript предоставляет вам возможность работы с коллекциями. Например, вы можете изменить свойства всех файлов в одном каталоге. В Active Directory это значит, что вы можете установить свойства, например, для всех пользователей в организационном модуле (OU).Чтобы сделать это вы должны установить указатель на OU и перечислить всех пользователей в нем как в коллекции.

Set CNUsers = GetObject ("LDAP://CN=Users,DC=sunnydale,DC=muni")
CNUsers.Filter = Array("user")
For Each User in CNUsers
HomeServer = User.msExchHomeServerName
DisplayName = User.displayName
WScript.Echo "HomeServer for" & DisplayName & "is" & HomeServer
Next

Вы можете также выбрать различные операции для различных типов объектов (называемых классами) в OU или просто сосчитать.

Здесь вы используете «Select Case» который служит как расширенное «If».

Set CNUsers = GetObject ("LDAP://CN=Users,DC=sunnydale,DC=muni")
Contacts = 0
Users = 0
For Each User in CNUsers
Select Case User.class
Case "user"
Users = Users + 1
Case "contact"
Contacts = Contacts +1
End Select
Next
WScript.Echo "Users:" & Users
WScript.Echo "Contacts:" & Contacts

Вы можете также захотеть произвести рекурсивный поиск, то есть искать во всех организационных модулях внутри одного организационного модуля(OU).

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

Set TopLevel = GetObject ("LDAP://OU=Domain Users,DC=sunnydale,DC=muni")
Contacts = 0
Users = 0
CountUsersContacts (TopLevel)

Sub CountUsersContacts (ObjOU)
For Each FoundObject in ObjOU
Select Case FoundObject.class
Case "user"
Users = Users + 1
Case "contact"
Contacts = Contacts +1
Case "organizationUnit","container"
CountUsersContacts (FoundObject)
End Select
Next

WScript.Echo "Users:" & Users
WScript.Echo "Contacts:" & Contacts

Так, главная программа вызывает подпрограмму «CountUsersContacts» с верхнего уровня OU «Domain Users» и если она находит OU внутри верхнего уровня OU, то она вызывает подпрограмму «CountUsersContacts» с этим OU как входным. В конце концов, все OU и их дочерние OU сканируются.

Если вы хотите просканировать весь домен, вы можете заменить следующую строку:

Set TopLevel = GetObject («LDAP://DC=sunnydale,DC=muni»)

Если вы также как и я пишите скрипты для пользователей, то имя домена не является константой, вы можете добавить несколько строк в начало скрипта чтобы определить корень текущего домена.

Set rootDSE = GetObject("LDAP://RootDSE")
domainContainer = rootDSE.Get("defaultNamingContext")
Set TopLevel = GetObject("LDAP://" & domainContainer)

В LDAP 3.0, rootDSE определен как корень каталога в дереве каталогов сервера. RootDSE это не часть пространства имен. Цель rootDSE поставлять данные о сервере каталогов, в этом случае Active Directory. Вы можете все еще привязать это к определенному серверу если вы хотите, изменяя эту строку:

Set rootDSE = GetObject("LDAP://MyGlobalCatalogServer/RootDSE")

Выполнение LDAP поиска

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

Constructing LDAP queries can be a complex matter. Active Directory предоставляет другую возможность поиска созднием LDAP запрос.

Следующая таблица показывает несколько примеров LDAP фильтров используемых в поиске:

Filter Description
(objectCategory=*) Все объекты
(&(objectClass=user)(!(cn=susan))) Все пользовательские объекты кроме susan
(sn=sm*) Все объекты с фамилиями, которые начинаются с sm
(&(objectClass=contact)(|(sn=Smith)(sn=Johnson))) Все контакты с фамилиями, которые равны Smith или Johnson

Как вы можете, видеть фильтры состоят из операторов, которые состоят из логических операторов и шаблонов, позволяя вам легко осуществлять поиск и управлять LDAP объектами и атрибутами, как показано в предыдущем примере.

Широко используемые в фильтрах LDAP поиска операторы

Operator Description
= Равно
~= Приблизительно равно
Лексикографически меньше чем или равно
>= Лексикографически больше чем или равно
& И
| ИЛИ
! НЕ

Создание и отладка LDAP запроса, особенно сложного запроса не легкая задача так как он может стать очень длинным и вы можете потеряться в его синтаксисе. К счастью для нас, разработчиков скриптов, Microsoft предоставляет возможность конструировать LDAP запрос используя Exchange System Manager (ESM).

Запускаем Exchange System Manager и создаем список адресов.

Щелкните правой кнопкой мыши на All Address Lists и выберите новый … Address List.

Дайте имя списку адресов и нажмите кнопку Filter Rules

Легкая в использовании диалоговая форма позволяет вам легко сконструировать запрос. В этом примере я ищу всех адресатов в Exchange, которые расположены в Огайо и принадлежат финансовому отделу.

После ввода запроса по вашему желанию нажмите кнопку ОК и затем Finish. Сейчас вы можете спросить «Где LDAP запрос» ? На странице свойств нового списка адресов вы можете увидеть его.

Вы можете также нажать кнопку предварительного просмотра (Preview) и увидеть результаты запроса. Вышеуказанный LDAP запрос может быть скопирован и использован в скрипте.

Есть возможность также в Windows 2003 создавать запросы с помощью Active Directory Users and Computers. Следующий скриншот покажет вам, как конструировать запрос, который будет использоваться в подсчете пользователей и контактов.

Сейчас строка запроса создана и мы наконец готовы для новой версии скрипта.

Set rootDSE = GetObject("LDAP://RootDSE")
DomainContainer = rootDSE.Get("defaultNamingContext")

Set conn = CreateObject("ADODB.Connection")
conn.Provider = "ADSDSOObject"
conn.Open "ADs Provider"
ldapStr = ";(&(&(& (mailnickname=*)
(| (&(objectCategory=person)(objectClass=user)(|(homeMDB=*)
(msExchHomeServerName=*)))(&(objectCategory=person)
(objectClass=contact)) ))));adspath;subtree"

Set rs = conn.Execute(ldapStr)

While Not rs.EOF

Set FoundObject = GetObject (rs.Fields(0).Value)
Select Case FoundObject.class
Case "user"
Users = Users + 1
Case "contact"
Contacts = Contacts +1
End Select
rs.MoveNext
Wend

WScript.Echo "Users:" & Users
WScript.Echo "Contacts:" & Contacts

Несколько строк были добавлены, чтобы установить LDAP соединение с Active Directory используя ADSI, и «rs» это указатель на коллекцию объектов имен каталогов полученных как результат LDAP запроса после того как он выполнен.

Так как это не коллекция указателей на объекты в Active Directory, а только на их имена, вместо использования «For Each…In» мы используем цикл «While Not [object].EOF…Wend» который улучшен использованием подпрограммы «MoveNext которая имеет преимущество, потому что использует внутренний индекс «rs». Чтобы проверить сам объект Active Directory, мы вызываем функцию GetObject с входным параметром rs.Fields(0).Value , который содержит имя каталога объекта.

Этот скрипт применяется ко всем объектам. Более эффективный скрипт может просто возвращать количество пользователей и количество контактов выполняя отдельные LDAP запросы и используя «RecordCount» свойство коллекции как показано ниже:

Set rootDSE=GetObject("LDAP://RootDSE")
DomainContainer = rootDSE.Get("defaultNamingContext")

Set conn = CreateObject("ADODB.Connection")
conn.Provider = "ADSDSOObject"
conn.Open "ADs Provider"
ldapStrContacts = ";(&(&(& (mailnickname=*)
(| (&(objectCategory=person)(objectClass=contact)) ))));adspath;subtree"
ldapStrUsers = ";(&(&(& (mailnickname=*)
(| (&(objectCategory=person)(objectClass=user)(|(homeMDB=*)
(msExchHomeServerName=*))) ))));adspath;subtree"

Set rs1 = conn.Execute(ldapStrContacts)
WScript.Echo"Contacts : "& rs1.RecordCount
Set rs2 = conn.Execute(ldapStrUsers)
WScript.Echo"Users : "& rs2.RecordCount

Заключение

Мы познакомились с несколькими способами доступа к объектам Active Directory и выполнению поиска. Это конечно только вершина айсберга, который возникает при овладении искусством управлять Active Directory и Exchange, используя скрипты, но это хороший старт, так как поиск объектов, чтение и запись их свойств является основой для Exchange скриптов.





Рейтинг:  
5.0 (голосов 5)  
 1   2   3   4   5    

Автор: Амит Зинман (Amit Zinman)
В настоящее время работает в качестве Менеджера Проекта и Системного Консультанта, руководя и консультируя в области миграций и разработок, основанных на Exchange и NT/Windows 2000, для больших компаний, таких как Checkpoint, Comverse, Smarteam, Nice, Aladdin и ведущих Банков Израиля. Также он участвует в написании скриптов и пользовательских решений для клиентов, основанных на ADSI, CDO и Visual Basic, и преподавании Windows 2000 и Exchange 2000 в MSCE колледжах и на лекциях в Microsoft User Groups.
Эта статья переведена и опубликована с разрешения http://www.msexchange.org

Эта статья переведена силами и средствами компании Red Line Software. Размещение данного переведенного материала на других сайтах без разрешения компании Red Line Software запрещается.





Работает на «Битрикс: Управление сайтом»
Работает на «Битрикс:
 Управление сайтом»
© MSExchange.ru, 2005-2010