Пару слов о провижининге сайтов под управлением IIS7

Недавно мне в роли консультанта пришлось выполнять небольшой проект, связанный с IIS7. Задача, в принципе, тривиальная - в рамках конкурсной программы для студентов по ASP.NET обеспечить хостинг сайтов всем желающим принять участие в таком конкурсе. Казалось бы - чего проще? - запускай IIS и создавай там сайты по мере необходимости. Но, как оказалось, не смотря на поднятую в ВУЗе, где все это планировалось делать, сеть под управления Active Directory, ответственным за поддержку сайтов был назначен со стороны ВУЗа, казалось бы, вполне подходящий на эту роль человек - системный администратор, занимающийся поддержкой сетей (Cisco) и веб-порталов (внутреннего и внешнего, на Linux). Нет, он не коим образом не был настроен против Windows Server 2008 и IIS7, просто для него лично это была лишняя, совершенно не нужная нагрузка - изучать новые технологии и все такое. Поэтому, посидев за пивком (первая итерация была назначена на выходные) мы достаточно быстро пришли к консенсусу, что идеальным выходом из ситуации было бы решение, которое позволяло ему простым скриптом создавать сайты на IIS7, базу данных для проекта на MS SQL Server 2005 и предоставлять доступ к вновь созданному сайту/базе через создаваемую отдельную учетную запись пользователя посредством ftp или консоли MS SQL. Итак, требовалось нечто, обеспечивающее простой провижининг в IIS, не вдаваясь во все тонкости процесса управления IIS со стороны плохо подготовленного админа. Вообще-то, у Microsoft есть решение для разработки систем провижининга под названием Microsoft Provisioning System Software Development Kit, но уж сильно оно мощное и всеохватывающее для такой небольшой задачи, да еще и требующее программинга, чего делать абсолютно не хотелось.

С другой стороны, на сайте сообщества IIS.NET есть серия статей, посвещенных планированию и провижинингу инфраструктуры IIS7 для общего хостинга сайтов. Эти материалы помогли не сколько с конкретными скриптами, сколько действительно с принятием решений относительно будущей архитеткуры моего маленького сценария работы. Итак, после чтения RTFM решение сложилось в голове довольно быстро и выглядело вполне лаконично.

  • новый FTP7 сервер, расширяющий возможности встроенного в IIS7 по умолчанию ftp-сервера, обеспечивающий изоляцию корневых (рутовых) каталогов ftp для каждого пользователя по его алиасу (User Isolation). Это позволило эффективно разделить все домашние каталоги веб-сайтов и предоставить к ним доступ только для владельцев. Создается заранее один сайт ftp и через него получают доступ все пользователи к содержимому своих ввеб-сайтов.
  • утилита appcmd.exe, являющаяся мощным инструментом управления всеми (в полном смысле этого слова) параметрами работы IIS7
  • и, в связи с особой ленью автора в написании любого кода - утилиты Administration Pack for IIS7 и SQL Server Management Studio. При чем здесь они? Да очень просто, кроме своих прямых задач по облегчению упраления теми или иными системами, обе утилиты позволяют генерировать скрипты для управления объектами. Именно эти утилиты и "нагенерили" мне нужные скрипты (например, AdminPack сгенерировал все, что касается команд управления IIS7 через appcmd.exe), после чего мне осталось только сделать обвязку в виде .CMD файла.

Вот, собственно, и .CMD файл, для работы которого используются 4 входящих парамера: алиас будущей учетной записи для управления сайтом пользователем, ID создаваемого сайта, полное имя пользователя в AD, пароль пользователя:

mkdir c:\userweb\IT\%1
rem создать каталог пользователя (по алиасу). IT - имя домена, с:\userweb - корневой калатог ftp сайта. пользователи будут получать свои каталоги как имя домана\алиас 

dsadd user "cn=%3,ou=Web Users,dc=it,dc=root,dc=edu,dc=ua" -samid %1 -pwd %4
rem создать пользователя в контейнере Web Users поддомена root.edu.ua

icacls c:\userweb\IT\%1 /grant IT\%1:(M)
rem предоставить права созданной учетной записи на работу с каталогом

appcmd.exe set config -section:system.applicationHost/sites /+"[name='%1',id='%2']" /commit:apphost
rem создать новый веб-сайт в IIS7 с именем по алиасу пользователя и указанным ID

appcmd.exe set config -section:system.applicationHost/sites /+"[name='%1',id='%2'].bindings.[protocol='http',bindingInformation='*:80:%1.university.edu.ua']" /commit:apphost
rem привязать к созданному сайту протокол HTTP, порт 80 и доменное имя ввиде <алиас>.university.edu.ua

appcmd.exe set config -section:system.applicationHost/sites /+"[name='%1',id='%2'].[path='/',applicationPool='DefaultAppPool']" /commit:apphost
rem привязать созданный сайт к пулу приложений по умолчанию 

appcmd.exe set config -section:system.applicationHost/sites /+"[name='%1',id='%2'].[path='/',applicationPool='DefaultAppPool'].[path='/',physicalPath='c:\userweb\IT\%1']" /commit:apphost
rem привязать к созданному сайту как домашний каталог ранее созданный каталог c:\userweb\IT\<алиас>, который доступен пользователю по ftp для редактирования содержимого сайта

sqlcmd -v dbname="%1" username="IT\%1" username2="%1" pwd="%4" -i createdb.sql -S dbserver
rem при помощи sqlcmd выполнить ранее сгенерированный консолью управления SSMS скрипт createdb.sql, создающий базу для пользователя и передать в нее значения

Все, администратору осталось только подключиться удаленно терминалом или через winrs к серверу с IIS и вполнить скрипт с нужными параметрами...

Файлы .cmd и вызываемый из него .sql смотрите во вложении к посту. Если же кому-то будет необходимо автоматизировать какие-то сценарии для работы с IIS7 - рекомендую сразу устанавливать AdminPack - он позволит вам на основе ваших предыдущих действий сгенерировать различные скрипты - как с применением appcmd, использованных в моем примере, так и, например, на C# коде, что позволит встраивать их в собственный код.

Об использовании AdminPack для автоматизации управления IIS7 я напишу в ближайшее время в продолжении данного поста. Кроме того, хочу заметить, что не смотря на использование AdminPack с его неплохими средствами визуализации статистики, на следующем этапе я воспользовался LogParser для сбора и визуализации статистики отдельных сайтов через веб. Об общих возможностях LogParser вы можете почитать в моей статье здесь, а о применении в конкретном примере я напишу вслед за постом об AdminPack.

create.zip