Все привет! В уходящем году хочу оставить небольшой след про такой сильный язык программирования, как PowerShell. Вероятно, уже в следующем году, ввиду тенденции отказа от Windows систем в нашей стране, моя практика в этой области закончится, а за пару лет активности, так и не собрался с силами опубликовать что-то подобное. Кода тут не будет, для этого у меня есть отдельная работа с заметками, цель статьи, еще раз подчеркнуть реальные возможности данного языка, где я буду ссылаться на работы, которые я старался делать универсальными, а так же сделаю акцент на полезных модулях.

Буквально два года назад, имея базовые знания навигации в консоли Linux, написание несложных batch-файлов и небольшой опыт VBScript открыл для себя PowerShell, и после этого я уже в прямом смысле этого слова, не мог остановиться реализовывать свои идеи, правда, такое дело очень затягивает. В один момент решился завести канал на GitHub и там же по сей день виду работу с заметками, где за это время накопилось более 6 тысяч строк из описания работы cmdlet (PowerShell-команд) и утилит для Системного Администратора (AD, Exchange, VMWare, MSSQL и т.д.) с примерами, ведь далеко не все получалось найти в интернете, порой, только изучая на практике свойства и методы объектов, можно получить желаемый результат. Так же набралась небольшая коллекция модулей и тестовый стенд WinForms с примерами работы различных методов, на котором я в дальнейшем базировался для написания приложений с графическим интерфейсом. Все работы писал по большей части для себя с целью автоматизировать и разгрузить текущий рабочий процесс, иногда помочь коллегам, именно по этому мне хочется поделиться своими наработками, возможно кому-то это еще сможет пригодиться.

Так сложилось, что многие с кем я общался, недолюбливают данный язык, порой, не воспринимают за язык вовсе, на рынке и правда для написания скриптов есть более функциональные конкуренты, но когда ты являешься администратором Windows систем, то это однозначно лучший, а порой незаменимый инструмент под рукой. Во-первых, язык является объектно-ориентированным, что сильно упрощает работу, и хотя в последнее время активно пишу на Bash, где преимущества в работе с текстом очевидны, но в силу привычки, мне очень не хватает данной модели, прибегая к сторонним инструментам, например jq и xmllint, которые нужно изучать отдельно, формировать массивы используя свой синтаксис. В PowerShell весь процесс автоматизирован и привычен. Во-вторых, язык на прямую интегрирован с платформой .NET, что дает возможности, как создание графических форм, используя WinForms и WPF, сетевые сокеты (например, можно написать свой syslog сервер), использовать различные библиотеки (изначально написанные на, или для C#), вплоть до создания и манипуляциями с графикой (создание или редактирование изображений).

Думаю очевидно, что для системного администратора графический интерфейс дает много возможностей, например, можно оптимизировать работу консольной команды или целого ряда cmdlet, не запоминая все ключи, имея возможность менять параметры наглядно в формах интерфейса. Автоматизировать процесс создания учетных записей в Active Directory, или формирование динамических табличный отчет состояния инфраструктуры VMWare (помимо набора модулей из PowerCLI присутствует целый ряд встроенных командлетов для Hyper-V) или Exchange (EMShell), где с помощью нескольких кликов можно узнать состояние всех баз данных и групп доступности в удобном формате, просмотреть message tracking log и выгрузить PST (возможность, которая отсутствует в консоли управления). Все это позволяет автоматизировать рутину, а главное, оптимизировать работу инструментов под себя. Естественно, никто не мешает выбрать другой интерфейс взаимодействия, например написать своего собственного бота Telegram или использовать Pipeline в Jenkins, где вся логика будет на PowerShell, и вероятно, для многих решения на базе скриптов могут казаться костыльными, тем не менее, это работает, а порой очень хорошо и других вариантов попросту может и не быть. Но в конечно итоге можно создать свою службу (используя бесконечный цикл и NSSM) или даже конвертировать скрипт в исполняемый exe-файл используя модуль ps2exe.

Фоновые задания (Jobs). Здесь смотря с кем сравнивать, например в Bash для управления jobs слишком мало функционала, они есть и работают неплохо, но по факту сами задания непредсказуемы и нуждаются в дополнительном логирование. По времени выполнения, тут все не очень хорошо, но наглядно, т.к. задания выполняются упорядочено (в отличие от Thread в Python). Для сравнения на ping 256 машин занимает примерно 2 минуты используя встроенный модуль, если воспользоваться модулем ThreadJob, время сокращается в среднем до 26 секунд, а вот задания через PoshRSJob уже 13 секунд.

Сравнение скорости работы модулей фоновых заданий
Сравнение скорости работы модулей фоновых заданий

А вот в Python это занимает всего 5 секунд уже с resolve именем хоста, где можно так же создать отдельный поток для графического интерфейса (в примере, TKInter).

Пример графического интерфейса для ping подсети на python.
Пример графического интерфейса для ping подсети на python.

Но эту проблему можно исправить, используя классы .NET, например, System.Net.Sockets.TcpClient для проверки портов, где можно определить timeout ожидания ответа в 100мс и ситуация становится более наглядной, и демонстрирует разницу, при проверки одного порта на всех 254 хостах, создание заданий с использования ThreadJob занимает в среднем на 30-40% меньше времени, чем пауза (Start-Sleep) в 100 миллисекунд.

Сравнение метода BeginConnect с и без использования ThreadJob (timeout 100 milliseconds).
Сравнение метода BeginConnect с и без использования ThreadJob (timeout 100 milliseconds).

Управлять же заданиями максимально удобно, т.к. есть возможность отслеживать их статус, узнать состояние и время работы, читать вывод, ставить на паузу и даже отслеживать историю выполненных заданий.

Возвращаясь с графическим интерфейсам, моей первой работой была RSA, которая к слову затянула меня на 8 месяцев и заключалась в реализации своей системы удаленного подключения и управления текущими сессиями пользователей на базе технологии Remode Desktop Shadow и упомянутого WinForms. Моей целью было отойти от нелюбимого мною коммерческого решения Radmin, активно использующегося в компании на тот момент.

Интерфейс последней версии RSA 1.4.1
Интерфейс последней версии RSA 1.4.1

В отличие от классического RDP, мы подключаемся на прямую к текущей сессии пользователя, а например от Radmin или AnyDesk, не требует установки программного обеспечения. Моей первой задачей было, с помощью какого инструмента отображать список активных пользователей на удаленной машине (преимущественно это терминальные фермы, в среднем по 10-12 пользователей на хосте) в объектном формате, что бы заполнять таблицу (DataGridView). Используя регулярные выражения вывод консольного приложения можно преобразовать в объект, это легло в основу многих моих идей, хотя не думаю, что она новая. Взяв за основу команду query.exe это можно сделать буквально в несколько строк (в данном примере специально добавлены комментарии). Данная коллекция заполняет таблицу, где при выборе пользователя, а по факту нужной строки и нажатии на кнопку "Connect", происходило подключение к пользователю с его ID текущей сессии из столбца 3.

Далее мне хотелось увеличить возможности удаленного администрирования без прямого взаимодействия с удаленным пользователем и добавить инструментов, за время работы у меня выработался определенный алгоритм, который я выполняю при анализе проблем в работоспособности операционной системы - это оценка нагрузки процессов, состояние служб, проверка uptime, последних обновлений и установленных приложений, состояние синхронизации компьютерных часов (ntp) и лицензий (kms), анализ сетевых настроен, подключений и конечно логов. Всем этим и не только возможно управлять удаленно, и у меня это получилось поместить в один интерфейс.

Работа с REST API. Есть одна ключевая особенность, PowerShell способен на прямую конвертировать вывод JSON и XML в объект (в обоих направлениях), что сильно оптимизирует работу для написания своих собственных скриптов взаимодействия с различными сервисами, для меня это остается самым удобно читаемым форматом, на фоне альтернатив, например, модулей для IDE. В остальном, преимуществ у Invoke-RestMethod или Invoke-WebRequest над curl особых нет. А вот для создания собственного REST API сервера вариантов наберется даже несколько. Имеется полноценный кроссплатформенный Web Framework Pode для создания REST API, веб-сайтов и серверов TCP/SMTP. Можно воспользоваться встроенным классом .NET HttpListener, на базе которого можно обработать все условия кодов возврата и использоваться базовую авторизация (Base64), и допустим создать возможность управления Windows системой на платформе Linux без необходимости конфигурирования WinRM - WinAPI, пример такой реализации.

В копилку кроссплатформенности, PowerShell Core очень неплохо работает в системе Linux, пусть и реализовано малая часть функционала, тем не менее можно комбинировать с другим языком, например Bash, и создать тот же простенький REST сервер.

Благодаря прямому взаимодействию PowerShell с ОС Windows и COM-объектами, вы можете создавать собственные кликеры на WScript для автоматизации любым простых действий (порой незаменимый подход по сей день, особенно, если это старые desktop Windows приложения), управлять продуктами MS Office (например, автоматическое создание подписи в Outlook с получением информации о пользователи из LDAP), создание и парсинг Excel-отчетов или автоматизация действий в браузере через Internet Explorer (альтернатива Selenium). Для примера у меня была задача, читать из smb каталога Excel-файл и смотреть на даты окончания срока доступа, по итогу такого совпадения делать рассылку на почту (указанную в столбце с Email и информацией в теле письма, о чем идет речь из столбца с описанием). Или, с указанным интервалом получать метрики измерений скорости интернета, используя Okkla Speedtest с выгрузкой их в InfluxDB и отрисовской в Grafana. Так же мне было удобно читать отчеты на почте состояния заданий и репозиториев Veeam, пока я нахожусь в дороге на работу, а позднее, написал модуль получения данных через REST API, который в дальнейшем развил до автоматизации добавления виртуальных машин в систему резервного копирования.

.NET Framework/Core. Модули есть практически для всего, можно даже создать собственный сервер мониторинга через WMI/CIM (фактически метрики дублируют Performance Counter), или библиотеку SNMP. Есть ряд библиотек для различных баз данных, таких как MS SQL (имеет 3 варианта взаимодействия, в том числе встроенный класс System.Data.SqlClient), MySQL Connector, SQLite, для других же присутствует стандартизированный программный интерфейс взаимодействия ODBC (присутствуют драйверы для PostgreSQL, Firebird, Elastic и т.д.). Примеры для работы с различными модулями можно посмотреть тут. У меня как-то была задача, реализовать рассылку оповещений об окончании срока действия лицензий из ITInvent (данная программа мне очень нравится своим удобством удобной, т.к. работал с ней в разных компаниях, но к сожалению данный функционал отсутствовал), где база крутилась в MS SQL Express на Oracle Linux, разобравшись во взаимосвязях между таблицами эту задачу получилось выполнить за 3 дня и на выходе всего 70 строк кода.

Selenium. Очень удобный и простой инструмент в первую очередь для функционального тестирования, но так же может быть полезен при автоматизации тех действий, для которых не предусмотрено API. Ключевой проблемой в PowerShell является отсутствие актуального готового решения подготовки всех зависимостей для работы с данным инструментом. Данный процесс подготовки у меня получилось автоматизировать, и как мне кажется, требует отдельного внимания, по этому планирую написать отдельную статью.

На этом пожалуй все. Осознаю, что многие решения нужно было описывать в свое время отдельной статьей, все работы это только энтузиазм, не являюсь разработчиком, весь опыт исключительно на практике. В освоение большинства тем очень помогали статьи различных источников, в т.ч. Habr и большая база знаний Microsoft, где так же присутствует браузер модулей PowerShell и .NET API.

Комментарии (14)


  1. dyadyaSerezha
    22.12.2023 13:51

    Да, это очень мощный скриптовый язык, но:

    1) Есть ли IDE, которая показывает/подсказывает свойства и методы у данного объекта или класса? А то задолбался руками это делать.

    2) Даже после 5 лет работы с PowerShell так и не привык к его "левому" синтаксису.

    3) Просмотрев десятки, если не сотни, предложений по работе за последние 2 месяца, помню буквально одно, где был упомянут PowerShell. Увы.

    Ну а вообще, почти весь Ansible на Виндах реализован через PowerShell.


    1. gadzhikuliev
      22.12.2023 13:51

      1. Visual Studio Code плюс расширения не подходит?


      1. dyadyaSerezha
        22.12.2023 13:51

        Вот даже не пробовал)


        1. Kenya-West
          22.12.2023 13:51

          Я пробовал! Работает очень хорошо, доволен всем. Все базовые манипуляции кода от написания до дебага работают, синтаксис светится, расширение активно развивается. Тесты к коду не писал, но, мне кажется, возможно и это.


          1. dyadyaSerezha
            22.12.2023 13:51

            Ну и ххх... хорошо. Пока PowerShell не в моих ближайших планах)


    1. Lifailon Автор
      22.12.2023 13:51

      1. Это отдельная боль, на протяжении всех 2-х лет занимался поиском такого IDE и лучше PowerGUI все же ничего нет, хотя работает не всегда стабильно с большими объектами WinForms (но кстати, порой удобнее все же смотреть в консоли, чем в браузере), нет поддержки c 2014 года, в целом интерфейс приятный и стабильный, напоминает NotePad++ с своими закладками и подцветкой изменений, присутствует режим отладки. Есть так же расширение для ISE - Steroids, менее привлекательно выглядит, но чуть более быстрый и имеет больше функционала, но там нужно платить, долго искал лицензию или другой обходной путь, не вышло. Ужасно работает PSScriptPad, пробовал тестировать в разное время, проверяя обновления. PowerShell Studio от компании SAPIEN, имеет классный WinForms конструктор, но познакомился я с ним поздно, и привычнее было уже писать все руками, из минусов еще, слишком перегруженный и тормозной. Долго противился VSCode и остановился на нем, читать объекты и его свойства можно в режиме отладки, как ограничение, но к этому нужно привыкнуть, а еще привыкнуть к большому количество переменных окружения, которые не скрыть (капался, так и не нашел как) и они через раз фильтруются в вкладках функции или цикла например, кстати работает супер быстро, я вообще отладкой начал пользоваться буквально полгода назад и очень редко, т.к. необходимости нет.
        Сейчас, к слову, занят поиском похожего решения, как PowerGUI, но для Python, вроде как только PyScripter может выводить и хранить переменные и свойства объектов без запуска в режиме отладки.

      2. Что значит "левый"?

      3. Все так, меня такая ситуация тоже крайне огорчает, потому что привык и очень полюбился мне этот язык, тем не менее приходится подстраиваться и размышлять в сторону развития изучения инструментов DevOps (jenkins, groovy, ansible, python и т.п.).


      1. dyadyaSerezha
        22.12.2023 13:51

        Левый, значит очень многословный и нетрадиционный.

        Кстати, а пинговать и делать что-то с десятками и сотнями машин лучше через Ansible, мне кажется.


      1. mc2
        22.12.2023 13:51

        а как же powershell ise?


  1. Tzimie
    22.12.2023 13:51

    https://habr.com/ru/articles/723730/

    Ужасы PowerShell


    1. gadzhikuliev
      22.12.2023 13:51

      Но есть и прелести. =)

      https://habr.com/ru/articles/737642/


  1. gadzhikuliev
    22.12.2023 13:51

    Видимо, изучение самого .NET, который даёт PowerShell-у огромные возможности, останавливало многих админов. Сколько знаю Windows-админов, изучивший Python, никто из них не углублялся в PowerShell + .NET. А зря, как очевидно.


    1. dyadyaSerezha
      22.12.2023 13:51

      PowerShell хорош тем, что в нем есть мощные админные/девопсные модули, которые на Python замучаешься писать.


  1. jackcrane
    22.12.2023 13:51

    у кого-нибудь есть 100% рабочий рецепт по затыканию телеметрии powershell без использование фаерволла (фаерволлом я и сам смогу) ? вот здесь:

    https://github.com/PowerShell/PowerShell/issues/10005

    шаманили как могли но результат не очевиден.


  1. eugrus
    22.12.2023 13:51

    Кроме командлетов, .NET и COM в PowerShell есть ещё и возможность импорта произвольных DLL-библиотек.