Отсоединенный набор записей (DRS) — это набор записей ADO, который находится в оперативной памяти. Объект DRS полностью отключен от исходного источника данных, и вы можете достаточно легко создать его «по требованию». С помощью простых запросов в стиле SQL можно осуществлять сбор данных из таких источников как Active Directory, а также получать полезную информацию.
Рассматриваемые в этой статье утилиты несложны, и они не являются реляционными базами данных. Это базы данных, состоящие из типичных коллекций данных, которые вы обычно анализируете с ежедневной или еженедельной периодичностью. Количество полей в этих базах данных минимально. Общее число записей обычно менее 10 тысяч, а размер файла и занимаемая память минимальны. Вы увидите, насколько эффективна работа с наборами записей такого размера.
Утилиты DRS сэкономят ваше время и обеспечат высокопроизводительный доступ к данным при небольшом объеме пространства, занимаемого на диске и в оперативной памяти. Эти утилиты, как правило, требуют минимум забот. Вы можете воспользоваться DRS многими способами. Если лучше всего подходят интерактивные запросы, можно сконструировать файл графического интерфейса пользователя .hta, который позволит вам находить наборы данных, соответствующие определенным запросам.
Если графический интерфейс пользователя не требуется, создайте DRS и анализируйте данные так, как вам это требуется, чтобы удобнее выполнять вашу задачу. Это может быть, к примеру, задача просмотра файла журнала электронной почты, который содержит идентификаторы пользователей и имена компьютеров, с заменой этих значений на другие.
На протяжении ряда лет технология DRS зарекомендовала себя как отличный ресурс для быстрого и эффективного выполнения таких утилит, как:
- Внесение изменений в журнал системы безопасности.
- Идентификаторы безопасности (SID) / базы данных с информацией о пользователях.
- SID / пользовательские таблицы просмотра перекрестных ссылок.
- Таблицы просмотра очередей печати.
- Еженедельные сравнения учетных записей администратора.
Чтобы создать DRS, нужно сначала создать объект ADO Recordset (ADOR). Вот два примера, как это сделать на VBScript:
Set DRS = CreateObject("ADOR.Recordset")
и:
Set DRS = CreateObject("ADODB.Recordset")
ADOR — это облегченный клиент ADO, который предоставляет только интерфейс для работы с набором записей. Если вы можете создавать экземпляры ADO, значит, вы можете создавать экземпляры ADOR. ADOR — это подмножество ADOdb, которое, в свою очередь, является подмножеством ADO. Я предпочитаю использовать ADODB.Recordset, но есть и альтернативный вариант.
Построение базы данных DRS не вызывает затруднений. Просто установите поля, которые вас интересуют, а затем заполните эти поля данными, полученными из источника, например, Active Directory.
В этом примере демонстрируется, как можно настроить вспомогательную базу данных для инструмента корректировки журнала безопасности:
Const adFldIsNullable = 32
Set DRS = CreateObject("ADODB.Recordset")
DRS.Fields.Append "SecurityObject",201,256,adFldIsNullable
DRS.Fields.Append "Type",201,256,adFldIsNullable
DRS.Fields.Append "Substitute",201,256,adFldIsNullable
DRS.Open
Обратите внимание, что в первой строке объявляется константа (Constant). Константа adFldIsNullable указывает, что поле может принимать пустые значения. В случае с инструментом корректировки поля всегда будут содержать данные. Включение константы не является необходимостью, и вы можете пропустить этот шаг, но этот никак не повредит. Однако если вы создаете базу данных с полями, которые могут не содержать данных, вам нужно объявить эту константу и использовать ее. Вот некоторые другие пояснения для этого варианта использования:
- Во второй строке создается объект DRS.
- В строках с третью по пятую определяются поля базы данных.
- В шестой строке объявляется открытие базы данных и готовность ее к приему данных.
Рассмотрим синтаксис оператора Fields.Append:
- Именем создаваемого поля является «SecurityObject».
- «201» указывает, что типом данных поля является длинная строка.
- «256» задает, что размер поля DefinedSize имеет переменную длину. (В соответствии с этим определением длина поля, превышающая 255 символов, будет интерпретироваться как переменная длина, что означает, что поле может хранить больше или меньше, чем 256 символов.)
- Атрибут поля adFldIsNullable указывает, что поле может принимать пустые значения.
Для получения информации о типах данных полей обратитесь к веб-странице MSDN DataTypeEnum. Для получения информации о длинах полей обратитесь к веб-странице Append Method (ADO).
Для добавления данных в базу данных просто выполните последовательность действий, подобную приведенной в этом примере:
DRS.AddNew
DRS("SecurityObject") = "172.172.\d\d?\d?\.\d\d?\d?"
DRS("SecurityType") = "IP"
DRS("Substitute") = "a1.b1.c1.d1"
DRS.Update
Вам не нужно вызвать метод DRS.Update после заполнения каждой записи. Вы можете подождать с этой командой то тех пор, пока не заполните весь набор записей. Метод Update просто фиксирует записи в базе данных и делает их доступными.
В предыдущем фрагменте кода я добавил в базу данных одну запись. Процесс будет использовать эту конкретную запись для поиска в текстовом файле журнала IP-адреса, начинающегося с «172.172», и замены его на «a1.b1.c1.d1».
Чтобы заполнить базу данных коллекцией Active Directory, содержащей имена компьютеров и серверов, я создаю запрос LDAP и заполняю базу данных, как показано в листинге 1.
Листинг 1 Создание запроса LDAP и заполнение базы данных
Const ADS_SCOPE_SUBTREE = 2
DNC = GetObject("LDAP://RootDSE").Get("defaultNamingContext")
Set objConnection = CreateObject("ADODB.Connection")
Set objCommand = CreateObject("ADODB.Command")
objConnection.Provider = "ADsDSOObject"
objConnection.Open "Active Directory Provider"
Set objCommand.ActiveConnection = objConnection
objCommand.Properties("Page Size") = 1000
objCommand.Properties("Searchscope") = ADS_SCOPE_SUBTREE
objCommand.CommandText = _
"SELECT cn FROM 'LDAP://" & DNC & "' WHERE objectcategory = 'computer'"
Set objRecordSet = objCommand.Execute
objRecordSet.MoveFirst
SubstCount = 1
Do Until objRecordset.EOF
DRS.AddNew
DRS("SecurityObject") = objrecordset.Fields("CN").Value
DRS("SecurityType") = "Host"
DRS("Substitute") = "Host" & SubstCount
SubstCount = SubstCount + 1
objRecordset.MoveNext
Loop
Каждая запись, создаваемая в этой последовательности, будет содержать имя компьютера со значением «Host» для Type и со значением «Hostnnn» для Substitute (здесь «nnn» представляет собой последовательный номер, например, «Host123»). Вы можете изучить код и увидеть, как пишется код для аналогичного процесса наполнения базы данных идентификаторами пользователей.
После того как вы заполнили базу данных и выдали команду Update, вы можете сортировать, прочитывать и фильтровать набор данных. Для просмотра базы данных сначала поместите указатель записи на первую запись, а затем настройте циклический процесс для обхода базы данных. Например:
DRS.MoveFirst
Do while Not DRS.EOF
myRegExp.Pattern = "\b" & Lcase(Trim(DRS.Fields.Item("SecurityObject"))) & "\b"
If myRegExp.Test(strNewText) Then
chng2 = Lcase(Trim(DRS.Fields.Item("Substitute")))
strNewText = myRegExp.Replace(strNewText,chng2)
End If
DRS.MoveNext
Loop
Циклический процесс будет продолжаться по тех пор, пока не будет достигнут маркер конца файла. Также важно обратить внимание на метод MoveNext, который обеспечивает перемещение указателя. Без него ваша программа войдет в бесконечный цикл.
При работе с базой данных вы сможете обращаться к значениям полей каждой из записей с помощью свойства Fields.Items, как можно видеть в третьей и пятой строках предыдущего фрагмента кода:
- DRS.Fields.Item(“SecurityObject”) будет содержать значение идентификатора пользователя или имени компьютера, взятое из коллекции Active Directory.
- DRS.Fields.Item(“Substitute”) будет содержать значение, которое заменит идентификатор пользователя или имя компьютера, если соответствующая запись будет найдена.
В предыдущем фрагменте кода вы не увидели операции открытия файла и чтения его в переменную. Это делается с помощью объекта регулярного выражения (Regular Expression), позволяющего находить строки в тексте и заменять их конкретными значениями.
Все искомые объекты находятся в поле базы данных под именем SecurityObject. Заменяющее значение находится в поле под названием Substitute. В этом примере база данных содержит все имена компьютеров и идентификаторы пользователей, которые существуют в заданном домене. Если в ходе выполнения цикла DRS находит в текстовом файле значение SecurityObject, оно заменяется на соответствующее значение Substitute.
Как только DRS достигает маркера конца файла, выполняется просмотр файла, запись обработанного текстового файла в файловую систему и передача его поставщику для утверждения. Вы можете использовать этот код «как есть» или адаптировать его по вашему желанию. Возможно, вы обнаружите, что следует подкорректировать код, чтобы пропускать совпадающие имена или слова, которые могут присутствовать в вашей коллекции Active Directory.
Это всего лишь небольшой пример того, что можно делать с помощью DRS, но я надеюсь, он будет для вас полезным. Есть еще масса вопросов касательно DRS, которые можно обсудить, например создание графического пользовательского интерфейса, который отображал бы функциональные возможности DRS, такие как сортировка, фильтрация и отображение записей в соответствии с запросами SQL.