ADG Оставить заявку
Блог Автоматизация 5 мин чтения

Windows PowerShell RC: первые скрипты для AD и файловых серверов

Microsoft выпустила Release Candidate PowerShell. После лет на VBScript и WSH наконец появился shell, с которым можно работать всерьёз. Разбираемся с синтаксисом и трогаем AD.

Контекст момента

Windows PowerShell 1.0 Release Candidate вышел в апреле 2006; финальный релиз ожидается позднее в том же году

Microsoft наконец выпустила Release Candidate того, что раньше называлось Monad, а теперь - Windows PowerShell. Мы следили за этим проектом с 2003 года: на TechEd показывали демонстрацию, и даже тогда было видно, что это что-то принципиально другое. Когда RC появился на загрузке, долго не думали.

Контекст важен. Несколько лет автоматизации на Windows у нас - это VBScript плюс WSH. Работает, но каждый скрипт - это примерно двести строк Dim, Set, CreateObject и COM-объектов, которые то есть, то нет в зависимости от версии ОС. Простая задача «пробежаться по всем компьютерам домена и проверить, у кого не запущен агент» превращается в получасовое развлечение с ADSI-запросами и разбором WMI-объектов. Cron на Linux мы освоили ещё в 2004-м, и разница в удобстве была постоянным поводом для зависти самим себе.

Первое впечатление от синтаксиса

PowerShell с первых минут ощущается непривычно, и это мягко сказано. Здесь всё - объекты. Не текст, не строки, которые ты парсишь грепом, как в bash, а настоящие .NET-объекты с методами и свойствами. Get-Process возвращает не строки про процессы - он возвращает объекты, у каждого из которых есть .Name, .CPU, .WorkingSet и ещё десяток свойств.

Пайп (|) тоже работает принципиально иначе: он гонит не текст, а объекты. Это поначалу ломает мозг, потому что рефлекс из bash - после пайпа пишешь awk '{print $2}'. Тут такого нет. Вместо этого:

Get-Process | Where-Object { $_.CPU -gt 100 } | Select-Object Name, CPU

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

Второй момент - командлеты написаны в формате Глагол-Существительное. Get-Service, Stop-Process, Set-Item. Через час работы начинаешь угадывать имя нужного командлета ещё до того, как заглянул в справку. Get-Help встроен и нормально работает - это отдельное удовольствие после попыток найти документацию по WScript.Shell в гугле.

Что попробовали в первую очередь: Active Directory

AD - главная боль на Windows-администрировании. Нас интересовало одно: можно ли нормально работать с пользователями и группами без написания простыни VBScript.

В RC пока нет нативных командлетов для AD (Microsoft обещает их в финале или позже), но работа через ADSI из PowerShell уже на порядок удобнее, чем то же самое на VBScript:

$domain = [ADSI]"LDAP://DC=company,DC=local"
$searcher = New-Object DirectoryServices.DirectorySearcher($domain)
$searcher.Filter = "(&(objectCategory=user)(department=Бухгалтерия))"
$searcher.FindAll() | ForEach-Object {
    $user = $_.GetDirectoryEntry()
    Write-Host $user.Name, $user.mail
}

Сравните это с аналогичным VBScript-кодом. VBScript: тридцать строк, половина из которых - объявления переменных и проверки на Nothing. PowerShell: семь строк, читаемых как обычный язык.

Первый реальный сценарий, который написали - выгрузка списка пользователей из конкретного OU с атрибутами для аудита. Раньше такой отчёт делали либо руками через ADUC, либо мучились с CSV-экспортом из ldifde. Теперь - скрипт на восемь строк, который делает это за минуту.

Файловые серверы: работа с ACL

Вторая задача, которая давно требовала нормального инструмента - проверка прав на файловых серверах. У клиентов накапливается ситуация: папки создаются годами, права выставляются вручную, схема прав превращается в кашу. Нужен инструмент, который пробежится по дереву и покажет, где права выбиваются из нормы.

$path = "\\fileserver\share"
Get-ChildItem -Recurse $path | ForEach-Object {
    $acl = Get-Acl $_.FullName
    foreach ($access in $acl.Access) {
        if ($access.IdentityReference -notlike "DOMAIN\*" -and
            $access.IdentityReference -notlike "BUILTIN\*") {
            Write-Host $_.FullName, $access.IdentityReference, $access.FileSystemRights
        }
    }
}

Скрипт ловит все папки, где в ACL есть записи, не принадлежащие доменным группам или встроенным аккаунтам. Раньше такой аудит занимал полдня ручной работы или требовал покупки специализированного инструмента. Теперь - скрипт, который запускается раз в неделю по расписанию через Task Scheduler.

Что не работает или неудобно

RC есть RC. Несколько вещей, которые раздражают прямо сейчас:

Нет нативного модуля для AD. Работа через [ADSI] и DirectorySearcher работает, но это не то, что хотелось бы видеть в конечном инструменте. Каждый раз нужно держать в голове синтаксис LDAP-фильтров.

Execution Policy по умолчанию запрещает запуск скриптов. Логика понятна - безопасность, - но на серверах это первое, что приходится менять через Set-ExecutionPolicy RemoteSigned. Неудобно при развёртывании на новых машинах.

Не хватает командлетов для сети. Базовые вещи - пинг, трассировка - либо делаются через WMI, либо через старые утилиты. Хочется Test-Connection с нормальным выводом объектов, а не вывод ping.exe, который потом нужно парсить.

Установка на каждую машину вручную. PowerShell не входит в состав Windows XP или Windows Server 2003 из коробки - нужно ставить отдельно. Для серверов, которые мы сопровождаем, это означает добавить установку в процедуру развёртывания нового сервера. Пока несложно, но масштабироваться будет с трением.

Ощущение в целом

После первой недели работы с RC - инструмент серьёзный. Не очередная надстройка над cmd, а полноценная среда автоматизации, которая наконец-то подходит для работы с Windows-инфраструктурой. Мощь объектного пайпа становится понятна примерно через час: когда можно взять вывод одной команды, отфильтровать по полю, отсортировать, выгрузить в CSV - всё в одну строку - это реально другой уровень.

Сравнивать с bash напрямую не хочется: разные среды, разные задачи. Но на Windows до сих пор не было ничего сравнимого, и это, пожалуй, главное.

RC пока в тестовых контурах, на продакшн-серверы не пойдёт до финального релиза. Но скрипты уже пишем - к моменту, когда выйдет 1.0, хотим иметь готовую библиотеку для типовых задач по AD, файловым серверам и сервисам.

Контакт

Нужна такая же инженерная работа?

Опишите задачу и контекст. Ответим в течение рабочего дня, при необходимости подпишем NDA.