Я не собираюсь акцентировать внимание на различиях между этими языками, вместо этого хочу показать, насколько сходным может быть код, написанный на языках Perl, VBScript, C#, b Visual Basic .NET. Для этого я продемонстрирую, как с помощью рассматриваемых языков реализуется простая, но достаточно актуальная задача - создание учетной записи пользователя в Active Directory (AD). Я не стану объяснять, как отображать на экране сообщение "Hello, World" на четырех языках, так как эта процедура проста и достаточно изучена.
Определимся с терминологией
Независимо от выбранного языка разработки, процедура создания любого объекта в AD, в том числе учетной записи пользователя, включает в себя четыре этапа:
- Подключение к контейнеру AD, в котором будет создаваться объект.
- Создание объекта.
- Установка тех обязательных атрибутов, которые не задаются в AD автоматически.
- Сохранение созданного объекта в AD.
У вас может возникнуть вопрос "Если это все, что нужно сделать, тогда почему я встречаю примеры процедур создания учетных записей пользователей, содержащие более 300 строк кода?" Здесь необходимо точно определиться с типами рассматриваемых примеров кода. Обычно мы сталкиваемся с двумя типами таких примеров: теми, которые носят исключительно учебный характер, и теми, которые представляют собой законченные решения.
Между учебными примерами и готовыми решениями имеется существенная разница. Законченное решение для создания учетных записей пользователей, скорее всего, будет содержать обработку ошибок (скажем, проверку существования учетной записи с таким именем перед ее созданием), вывод данных на консоль, кроме того, возможно, что в этом решении будут задействованы еще какие-либо процедуры. Так, например, сведения о создаваемых учетных записях пользователей могут считываться из некоторой таблицы, а затем эти данные будут использоваться при создании учетных записей. Что касается учебного примера, то здесь будут показаны только те шаги, которые непосредственно относятся к решаемой задаче. Таким образом, учебный пример создания учетной записи в AD будет содержать не более четырех-пяти строк кода. Разумеется, такое различие между учебным примером и готовым решением имеет место не только в случае создания пользовательской учетной записи в AD. В принципе, независимо от выбранного языка разработки, суть практически любой задачи, выполняемой администратором, может быть сведена к нескольким строкам кода.
Выбор языков
Чтобы показать, как происходит процесс создания учетной записи, я выбрал два языка разработки сценариев (VBScript и Perl) и два языка программирования (Visual Basic .NET и C#). VBScript, вероятно, является наиболее простым для понимания языком, к тому же он в полной мере поддерживается Microsoft как инструмент системного администрирования Windows. Perl тоже является естественным выбором, поскольку это весьма распространенный кросс-платформенный язык сценариев, используемый многими администраторами систем Windows, Unix и Linux. Что касается Visual Basic .NET и C#, то они были выбраны из тех соображений, что оба эти языка включены в Windows .NET Framework и являются наиболее популярными языками программирования для данной среды. К тому же, если у вас есть навыки работы с Visual Basic (VB) или VBScript, вам будет достаточно просто разобраться в языке Visual Basic .NET. И, аналогично, если вы знакомы с JScript или Java, у вас не должно возникнуть проблем с C#.
Упрощение задачи
Если вы никогда ранее не программировали ни на одном из этих языков, не отчаивайтесь. Вы будете удивлены, насколько просто писать программы, если четко ограничить решаемую задачу и отсеять все вспомогательные моменты. Некоторые могут возразить, что это чрезмерное упрощение как технологии написания сценариев, так и процесса разработки вообще. Однако ключевым принципом освоения любой технологии, в том числе программирования, является рассмотрение на начальном этапе простых примеров, демонстрирующих способы решения стандартных задач. Разобравшись в том, как пользоваться технологией, вы будете лучше подготовлены к погружению в такой сложный предмет, как программирование. Примеры кода, показанные в Листингах 1, 2, 3 и 4, реализуют описанную ниже последовательность действий, выполняемых при создании учетной записи пользователя:
- Подключение к организационному подразделению (OU) TechWriters в домене fabrikam. com.
- Создание учетной записи для пользователя Ken Myer.
- Присвоение обязательному (mandatory) атрибуту sAMAccountName значения MyerKen.
- Сохранение созданной учетной записи в OU TechWriters.
Но не спешите сразу же запускать этот код. Сначала необходимо выполнить ряд подготовительных мероприятий. Во-первых, для того чтобы можно было запускать примеры, требуется выполнить ряд настроек на клиенте и сервере. Во-вторых, необходимо проверить, пригодна ли существующая клиентская инфраструктура для запуска данного кода. И, в-третьих (исключая примеры, реализованные на VBScript), в текст каждого из примеров, решающих конкретную задачу, необходимо добавить еще пару строк кода. А теперь давайте рассмотрим все перечисленные подготовительные процедуры.
Конфигурирование клиента и сервера
Для начала необходимо проверить, является ли ваш клиентский компьютер членом домена fabrikam.com и есть ли в этом домене OU TechWriters. Также убедитесь, что в этом домене нет пользовательской учетной записи с атрибутом sAMAccountName MyerKen, а в OU TechWriters нет учетной записи пользователя с общим именем (common name - CN) Ken Myer.
Конечно, я мог бы сделать эти примеры более гибкими, но тогда пришлось бы усложнять их код, что противоречит основной цели статьи - создание учебных примеров. Как уже упоминалось, можно редактировать код, приведенный в листингах, и выбирать другие имена для домена и для создаваемой учетной записи пользователя. Ниже показано несколько примеров внесения подобных изменений:
- В строке 1 замените ou=TechWriters, dc=fabrikam,dc=com на ou=HR,dc= adatum,dc=com. Тем самым вы обеспечите подключение к OU HR домена adatum.com.
- В строке 2 замените CN=Ken Myer на CN=John Doe. В этом случае вместо имени Ken Myer будет использоваться имя John Doe.
- В строке 3 замените MyerKen на DoeJohn. При этом атрибут sAMAccountName создаваемой учетной записи будет иметь значение DoeJohn вместо MyerKen.
Подготовка среды для выполнения сценариев
Для реализации поставленных задач на том или ином языке сценариев необходим исполнительный механизм, интерпретатор языка и соответствующие объекты COM. В среде Windows имеется компонент Windows Script Host (WSH), который является исполнительным механизмом, позволяющим запускать и выполнять сценарии. Компонент WSH по умолчанию включается в состав всех операционных систем, начиная с Windows 2000, однако нужно обновить его до версии WSH 5.6. Это следует сделать для всех Windows-платформ, за исключением Windows Server 2003 (в него уже включена последняя сборка WSH 5.6). Компонент WSH 5.6 можно загрузить с сайта Microsoft по адресу http://msdn.microsoft.com/scripting.
Сценарии, написанные на VBScript, могут запускаться через WSH без каких-либо дополнительных ухищрений, поскольку WSH имеет встроенный интерпретатор языка VBScript. Что же касается Perl, то хотя Microsoft не включила в WSH интерпретатор для этого языка, его легко установить. Зайдите на страницу http://www.activestate.com/products/download/download.plex?id=activeperl и загрузите установочный MSI-файл (в формате Windows Installer) пакета ActivePerl версии 5.8.1 или более поздней. После установки интерпретатора Perl сценарии, написанные на этом языке, могут также запускаться с помощью WSH.
Объекты COM, предназначенные для администрирования AD с помощью сценариев содержатся в компоненте ADSI (Active Directory Service Interfaces). Данный компонент включен в состав операционных систем версии Windows 2000 и более поздних. Для систем Windows NT 4.0 Service Pack 6a (SP6a) и Windows 9x компания Microsoft разработала специальное расширение AD Client Extensions. Расширение для клиентов Windows 9x имеется на установочном компакт-диске Windows 2000. AD Client Extensions для NT Workstation 4.0 можно загрузить по адресу: http://www.microsoft.com/ntworkstation/downloads/other/adclient.asp.
Подготовка среды для выполнения управляемого кода
Для выполнения заданий, разработанных на языках управляемого кода (в нашем случае это Visual Basic .NET и C#), необходимо наличие классов Microsoft .NET. Классы .NET имеются в составе операционных систем Windows 2003 и последующих версий. Для большинства операционных систем семейства Windows можно загрузить с сайта Microsoft Windows Update компонент .NET Framework 1.1, который содержит классы .NET и другие нужные программные средства. Если вы выполняете поиск обновлений с компьютера, на котором компонент .NET Framework 1.1 не установлен, он отобразится на сайте Microsoft Windows Update в меню Pick updates to install в разделе Windows или Windows XP, в зависимости от типа операционной системы, для которой вы запускаете установку обновлений.
Компонент .NET Framework 1.1 может устанавливаться на компьютеры с Windows 2003, Windows XP, Windows 2000, Windows Me и Windows 98. На них также должен быть установлен Microsoft Internet Explorer (IE) версии 5.01 или более поздней. Для того чтобы проверить, установлен ли на компьютере компонент .NET Framework 1.1, запустите приложение "Установка и удаление программ" в панели управления и посмотрите, есть ли там строка с названием "Microsoft .NET Framework 1.1". Другой способ предполагает проверку наличия каталога \%windir%Microsoft.NETFrameworkv1.1.4322. Число 4322 в имени каталога указывает на номер сборки Framework версии 1.1, к декабрю 2003 года данная сборка была самой последней. Более подробные сведения о Framework можно найти по адресу http://msdn.microsoft.com/netframework.
Компилирование кода
Сценарии интерпретируются WSH во время выполнения, поэтому предварительная компиляция не требуется. Что же касается управляемого кода, то он перед запуском обязательно должен быть откомпилирован. В случае больших и сложных программ компилированный код выполняется быстрее, чем интерпретируемый, кроме того, компилированный код по сути является более безопасным. Можно еще много чего сказать по поводу компилированного и интерпретируемого кода, однако для целей данной статьи достаточно просто усвоить, что управляемый код перед запуском необходимо компилировать.
В состав компонента Framework включены два инструмента компиляции управляемого кода. Для Visual Basic .NET имеется компилятор командной строки vbc.exe, для языка C# аналогичный компилятор называется csc.exe. Оба приложения находятся в родительском каталоге Framework. В случае .NET Framework 1.1 данный каталог называется v1.1.4322. В целях удобства (для того чтобы при запуске компиляторов не задавать полный путь) рекомендую указать путь \%windir%Microsoft.NETFrameworkv1.1.4322 в переменной окружения Path. Не забудьте заменить %windir% на актуальное название каталога Windows. Разумеется, если у вас установлен пакет Visual Studio .NET, в этом случае вам не надо переходить в каталог Framework или прописывать соответствующие пути в переменной Path - вы можете компилировать управляемый код прямо из командной строки Visual Studio .NET или через Visual Studio .NET IDE.
Однако перед тем как компилировать примеры, написанные на языках C# и Visual Basic .NET, необходимо дополнить их несколькими строками кода. В следующем разделе я опишу эти дополнения, после чего дам пояснения к командам компилятора и параметрам, которые необходимы для компиляции этих примеров.
Подготовка примеров
Код каждого из примеров требует небольшой подготовки к запуску. Что касается примера на VBScript, просто скопируйте содержимое Листинга 1 в текстовый файл и сохраните его в каком-либо каталоге под именем Listing1.vbs. Другие файлы примеров можно сохранять здесь же.
В примере на языке Perl необходимо в начало теста сценария вставить строку use Win32::OLE, как показано в Листинге 5. Здесь Win32::OLE - имя модуля Perl, который, помимо прочих функций, предоставляет возможность использования COM-библиотек Windows. В частности, в рассматриваемом примере будут применяться COM-библиотеки в ADSI. Скопируйте текст Листинга 5 в текстовый файл и сохраните его с расширением .pl.
Примеры на языках Visual Basic .NET и C# должны быть дополнены несколькими строками кода в начале и в конце, как показано в Листинге 6 и Листинге 7. Данные строки необходимы, причем они не являются специфическими только для рассматриваемых примеров. Более подробное описание этих дополнительных строк можно найти во врезке "Окружающий код для Visual Basic .NET и C#".
Для того чтобы откомпилировать пример на Visual Basic .NET, скопируйте в текстовый файл код Листинга 6 и сохраните его как файл с именем listing6.vb. Для того чтобы создать исполняемый файл listing6.exe, следует перейти в командной строке в ту папку, в которой вы сохранили файл, и запустить команду:
vbc /t:exe /r:system.dll /r:system.directoryservies .dll listing6.vb
Утилита Vbc, компонент Framework, позволяет компилировать в командной строке исходный код, написанный на языке Visual Basic .NET и создавать из него приложение. Ключ /r указывает программе vbc в каких библиотеках DLL содержатся классы, необходимые для запуска создаваемого приложения (эти DLL входят в состав компонента Framework). Имя lisitng.vb в данном случае определяет имя файла, содержащего исходный код.
Для того чтобы откомпилировать пример на C#, скопируйте в текстовый файл код Листинга 7 и сохраните его как файл с именем listing7.vb. Для того чтобы создать исполняемый файл listing7.exe, перейдите в командной строке в ту папку, в которой сохранили файл, и запустите команду:
csc /t:exe /r:system .directoryservices.dll listing7.cs
В данном случае утилита Csc, являющаяся компонентом Framework, позволяет компилировать в командной строке исходный код, написанный на языке C#, и создавать из него приложение. Ключи командной строки здесь работают аналогично только что рассмотренному примеру компиляции кода Visual Basic .NET с помощью vbc. Отличие состоит в том, что при компилировании кода C# не требуется указывать класс system.dll.
Запуск примеров
В целях сохранения связности изложения, каждый из рассматриваемых примеров использует одно и то же OU, имя CN (Ken Myer) и одно и то же значение атрибута sAMAcccountName (MyerKen). Поэтому после запуска каждого из примеров необходимо запустить оснастку AD Users and Computers консоли MMC (Microsoft Management Console) и удалить в OU TechWriters учетную запись пользователя Ken Myer. Запуск всех примеров осуществляется двойным щелчком мыши на соответствующем файле сценария или исполняемом файле. Можно запускать примеры и из командной строки, для этого надо перейти в соответствующий каталог, ввести имя нужного файла и нажать клавишу ENTER.
Итак, мы рассмотрели процесс создания в AD учетной записи пользователя на четырех разных языках программирования. Идея состоит в том, чтобы выделить суть выполняемой задачи и работать только над ней. При этом каждый из языков предоставляет удивительно похожие подходы к реализации решения интересующей задачи.
В следующих статьях я постараюсь усложнить рассмотренную задачу с тем, чтобы можно было задавать информацию о пользовательской учетной записи в командной строке, работать с несколькими учетными записями и обрабатывать ошибки.
ЛИСТИНГ 1: Код на языке VBScriptSet objOU = GetObject("LDAP://ou=TechWriters,dc=fabrikam,dc=com")Set objUser = objOU.Create("user", "cn=Ken Myer")objUser.Put "sAMAccountName", "myerken"objUser.SetInfoЛИСТИНГ 2: Код на языке Perlmy $container = Win32::OLE->GetObject("LDAP://ou=TechWriters,dc=fabrikam,dc=com");my $user = $container->Create("user", "cn=Ken Myer");$user->Put("sAMAccountName", "MyerKen");$user->SetInfo();ЛИСТИНГ 3: Код на языке Visual Basic .NETDim OU As New DirectoryEntry("LDAP://ou=TechWriters,dc=fabrikam,dc=com")Dim User As DirectoryEntry = OU.Children.Add("CN=Ken Myer", "user")User.Properties("samAccountName").Value = "MyerKen"User.CommitChanges()ЛИСТИНГ 4: Код на языке C#DirectoryEntry OU = new DirectoryEntry("LDAP://ou=TechWriters,dc=fabrikam,dc=com");DirectoryEntry User = OU.Children.Add("CN=Ken Myer","user");User.Properties["samAccountName"].Value = "MyerKen";User.CommitChanges();ЛИСТИНГ 5: Окончательный вариант кода на Perluse Win32::OLE;my $container = Win32::OLE->GetObject("LDAP://ou=TechWriters,dc=fabrikam,dc=com");my $user = $container->Create("user", "cn=Ken Myer");$user->Put("sAMAccountName", "MyerKen");$user->SetInfo();ЛИСТИНГ 6: Окончательный вариант кода на Visual Basic .NETImports System.DirectoryServicesModule Listing6Sub Main()Dim OU As New DirectoryEntry("LDAP://ou=TechWriters,dc=fabrikam,dc=com")Dim User As DirectoryEntry = OU.Children.Add("CN=Ken Myer","user")User.Properties("sMAccountName").Value = "MyerKen"User.CommitChanges()End SubEnd ModuleЛИСТИНГ 7: Окончательный вариант кода на C#using System.DirectoryServices;class Listing7{static void Main(string[] args){DirectoryEntry OU = newDirectoryEntry("LDAP://ou=TechWriters,dc=fabrikam,dc=com");DirectoryEntry User = OU.Children.Add("CN=KenMyer","user");User.Properties["sAMAccountName"].Value = "MyerKen";User.CommitChanges();}}
Окружающий код для Visual Basic .NET и C#
Первые строки кода в Листинге 6 и Листинге 7 являются дополнительными инструкциями сокращенной записи, которые указывают на то, что данное приложение использует один или несколько классов из пространства имен DirectoryServices. Говоря обычным языком, если не добавить в программу эти строки, вам придется использовать полную запись в каждой строке кода. Например, в третьих строках Листинга 3 и Листинга 4 вам пришлось бы писать не DirectoryEntry, а System. DirectoryServices.DirectoryEntry. Ключевые слова Module (Листинг 6) и class (Листинг 7) определяют имена блоков кода, а код блока пишется внутри скобок. Ключевое слово Sub с параметром Main() (Листинг 6), а также ключевые слова static и void внутри параметра Main(string[] args) (Листинг 7) задают в приложениях стартовую точку (или, в терминологии программирования, точку входа). Более подробные сведения о коде содержатся в справочных руководствах программиста Programmer's Reference для языков Visual Basic .NET и C#. Эти руководства можно найти в библиотеке Microsoft Developer Network Library (MSDN).