Всем привет! Порой, написать графическую форму для консольного приложения может оказаться очень удобным решением, тем самым не нужно запоминать все ключи программы, особенно, если пользоваться им приходится изредка, тем самым автоматизируя работу с данным приложением в дальнейшем. Но, ситуация может быть обратной, когда приложение имеет только графический интерфейс, а вам нужно получить вывод его работы в консоли, например, для возможности передачи метрик в систему мониторинга. С тех пор как начал проводить все больше времени в консоли, заметил, что становится менее удобно переключаться на ранее привычные инструменты, лишний раз использовать мышь, держать открытыми излишние приложения или вкладки в браузере, особенно, если работаешь на удаленной машине без прямого доступа к графическому интерфейсу. У меня накопилась небольшая коллекция полезных модулей, большинство из которых написаны совсем недавно, успел привыкнуть при регулярном использовании и хотелось бы ими поделиться. Осознавая, что тенденция ухода Windows систем на территории РФ растет, тем не менее думаю еще очень много людей, кто так же как и я продолжают использовать данную систему и автоматизировать свою работу, возможно, представленные модули так же смогут пригодятся. Все модули опубликованы в репозитории на GitHub и менеджере пакетов Nuget, откуда их можно установить одной командой.
PowerShell модуль представляет собой набор функций, которых объединяет между собой файл с расширением psm1 и манифест psd1 (последний не обязателен для работы модуля, нужен для его описания). Модули используют для взаимодействия с приложением или целой системой (например, система хранения TrueNAS, резервного копирования Veeam, виртуализации VMWare или Hyper-V, различными системами баз данных и т.п.), с возможностью повторного применения описанных в нем функций на уровне системы и его массового распространения через менеджеров пакетов. Еще модуль можно воспринимать как cli (интерфейс командной строки) для конкретного приложения, тем самым позволяя взаимодействовать с ним оперируя параметрами в консоли, при этом имея возможность для дальнейшей автоматизации или интеграции с другими сервисами напрямую через язык PowerShell. Например, команда для вывода содержимого файлов в консоли Get-Content, или более привычный для Linux систем псевдоним cat по факту представляет PowerShell функцию, базирующуюся на .NET, которая в свою очередь входит в состав модуля Microsoft.PowerShell.Management.
Console-Translate
На протяжении нескольких лет я пользуюсь переводчиком DeepL практически на ежедневной основе. Меня не всегда устраивает то, что у него есть ограничение в 1500 символов, тем не менее, так как у него есть полноценное десктопное приложение, это удобная альтернатива браузерным решениям, которое всегда под рукой на горячей клавише. Сменив место работы, и получив ограничение в самостоятельной установке какого-либо стороннего программного обеспечения на рабочем ноутбуке, пришлось задуматься в сторону альтернативного и простого решения, так как пользоваться переводчиком и при этом консолью я реже не стал, пришла идея использовать единый интерфейс. Для доступа к переводу текста в консоли можно использовать REST API, к сожалению, получить бесплатный ключ доступа DeepL для России невозможно, но тут можно найти много альтернатив. Во-первых, существует проект DeepLX с открытым исходным кодом, с помощью которого можно запустить свой бесплатный API-сервер, который может быть доступен одновременно нескольким пользователям в сети. Во-вторых, каждый, кто использует расширение Google Translate в своем браузере может перехватить публичный API-ключ (используя интерфейс DevTools во вкладке Network) с возможностью его использования через любой REST-клиент в консоли. И в-третьих, существует немало бесплатных провайдеров для перевода текста с наличием API, например MyMemory, которая содержит одну из крупнейших баз для переводов. Все перечисленные сервисы получилось внедрить в один модуль Console-Translate, который можно установить в своей консоли с помощью одной команды:
Install-Module Console-Translate -Repository NuGetНеобходимо, чтобы предварительно у вас в системе уже был зарегистрирован менеджер пакетов Nuget:
Register-PSRepository -Name "NuGet" -SourceLocation "https://www.nuget.org/api/v2" -InstallationPolicy TrustedСинтаксис простой, в первый параметр передается текст (если вы используете более одного слова, обязательно необходимо заключить весь передаваемый текст в кавычки), второй (через пробел) отвечает на язык назначения, например так:
> Get-Translate "Как дела?"
How are you?
> Get-Translate "Как дела?" de
Wie geht es Ihnen?По умолчанию перевод происходит между Русским и Английским языком в обоих направлениях, с автоматически определением языка на уровне PowerShell. Т.к. на уровне API не всегда хорошо срабатывает определение языка, добавил достаточно простую реализацию, так как акцент сделан на двух языках, каждый раз происходит подсчет переданных букв с разбивкой (методом Char) на русские и английские символы, букв какого из языков окажется больше, тот и будет являться исходным языком, и соответственно второй будет являться языком назначения (пример на скриншоте ниже).
Перевод текста в консоли через PowerShell на Linux и Windows машинах
С появления версии PowerShell Core данный язык является кроссплатформенным, по этой причине модуль будет работать в системе Linux, где я так же часто его использую, как и сам язык в силу привычки.
CrystalDiskInfo
У программы CrystalDiskInfo нет командного интерфейса для прямого взаимодействия через консоль, есть возможность только сформировать файловый отчет, где содержится много лишней информации в текстовом виде. Помимо этого отчета, программа так же хранит информацию в конфигурационных ini-файлах, которые обновляются в процессе сканирования или изменения настроек. Модуль CrystalDisk-Cli читает эти конфигурационные файлы и выводит результат в формате OSObject или Collection (необходимо, что бы программа CrystalDiskInfo уже была установлена). Вывод работы модуля будет выглядеть так:
Установить модуль CrystalDisk-Cli можно также одной командой:
> Install-Module CrystalDisk-Cli -Repository NuGet
> Import-Module CrystalDisk-Cli
> Get-DiskInfo
Name : WD PC SN740 SDDPNQD-1T00-10272243A5454811
Date : 2024/02/19 11:16:48
HealthStatus : 1
Temperature : 48
PowerOnHours : 1010
PowerOnCount : 448
Life : 100
HostWrites : 10322
HostReads : 10092
01 : 0
02 : 0
03 : 0
04 : 0
05 : 0
ReallocatedSectorsCount : 0
06 : 0
07 : 0
08 : 0
09 : 0
0A : 0
0B : 0
0C : 0
0D : 0
0E : 0
0F : 0Если необходимо обновить информацию и получить актуальный отчет, используется параметр Report (если консоль не запущена с правами администратора, при запуске появится окно, которое запросит подтверждение). Само приложение производит автоматическое обновление с заданным промежутком времени, которое можно изменить в настройках программы, например каждые 5 минут, используя команду: Get-DiskInfoSettings -AutoRefresh 5 (при запуске без параметров вернет текущие настройки, для изменения настроек понадобится запустить консоль с правами администратора). Вот пример вывода для нескольких дисков:
Вывод работы модуля CrystalDisk-Cli
Everything
Install-Module PSEverything -Repository NuGet
Find-Everything ".temp" -ComputerName plex-01 -Port 9999 -User every -Password thing # удаленное получение данных
Find-Everything ".temp" # локальное получение данных
$(Find-Everything ".temp").Count # посчитать количество файлов, подходящих под критерии поискаПоиск файлов через модуль PSEverything
Программа не содержит открытый исходный код, перед написанием модуля я ознакомился с правами лицензионного соглашения, которые крайне лояльны, и дают возможность интегрировать данное приложение для своих целей. Мне данный модуль очень мог автоматизировать поиск файлов для нескольких несложных скриптов, что было бы сложнее реализовать средствами PowerShell, не говоря про скорость работы, которая чаще не превышает 200мс (повышенная задержка при большом количестве найденных файлов вызвана не программой, а самим языком при обработке получаемых данных).
SpeedTest
У меня как-то была задача, реализовать мониторинг скорости интернета получаемую от провайдера на регулярной основе. Для примера, можно воспользоваться всеми известным Speedtest от Ookla, у данного сервиса уже присутствует cli-интерфейс, вывод которой можно распарсить, но это не единственный провайдер для предоставления подобный услуги и требует зависимость в виде исполнимого файла. В случае c встроенным Windows PowerShell версии 5.1 есть возможность использовать Internet Explorer через COM интерфейс, тем самым в браузере автоматизировать нажатие кнопок в фоновом режиме и забирать содержимое страницы прямо в консоль, для дальнейшей обработки и вывода в формате объекта, как это реализовано в модуле Ookla-SpeedTest-API. Вот пример:
Get-PackageProvider # проверяем, что провайдер пакетов nuget установлен
Find-PackageProvider # отобразить все допступные менеджеры пакетов
Install-PackageProvider nuget # установить менеджер пакетов nuget
Set-PackageSource nuget -Trusted # разрешаем установки пакетов из указанного источника
Find-Package Ookla-SpeedTest # ищем пакеты по названию во всех менеджерах
Install-Module Ookla-SpeedTest -Scope CurrentUser # установить модуль для текущего пользователя
### Запускаем модуль и забираем метрики
$test = Invoke-SpeedTest
$test | Select-Object date,download,upload
date download upload
---- -------- ------
19.02.2024 14:00:15 37263 19320Измерение скорости интернета через Ookla Speedtest в PowerShell 5.1
Используя такой модуль, можно настроить отправку метрик в базу данных и вывести данные на dashboard Grafana (такой пример с созданием службы есть на GitHub). Хотя данный подход уже является устаревшим, он не требует никаких зависимостей, но при этом не поддерживается в версии PowerShell Core. Для подобных целей правильнее использовать библиотеку Selenium (версии dotNET), например через браузер Chrome/Chromium, подробнее про установку зависимостей и создание модулей я уже писал пост на Habr. Вот пример вывода на примере OpenSpeedTest и LibreSpeedTest:
Измерение скорости интернета через Open и Libre Speedtest в PowerShell Core
Сервер и клиент Syslog
Маловероятно, что вам понадобится запустить сервер для сбора логов на системе Windows, при условии, что чаще для этих целей используют сервера на базе Linux, к тому же имеется достаточно большое количество отличных альтернатив, например Visual Syslog. Но если у вас есть запрет на запуск какого-либо стороннего программного обеспечения на системах Windows (что в моем случае и послужило причиной) или например PowerShell скрипт, события работы которого необходимо настроить для передачи серверу Syslog, данный процесс можно автоматизировать с помощью модуля pSyslog. Для установки и запуска серверной части используйте следующие команды:
Install-Module pSyslog -Scope CurrentUser
Start-pSyslog -Port 514
Get-pSyslog # читает входящие сообщения в реальном времени
Show-pSyslog # читает локальный файловый журналДля отправки сообщения на любой сервер Syslog, используйте команду Send-pSyslog:
Отправка сообщения на сервер Syslog
Серверная и клиентская часть базируются на классе .NET System.Net.Sockets, все источники документации и примеры работы есть в описании репозитория. Модуль поддерживает шифрование Base64, UDP Relay и ротацию локального журнала, который возможно настроить для получения метрик, например, по типу сообщения или содержимому. Протестировано в работе для версии Windows PowerShell на разных билдах до 3-х одновременных клиентов, также работает в версии Core.
Windows API
Модуль ps.win.api – это полноценный REST API и Web сервер на чистом PowerShell, серверная часть которого базируется на классе .NET HttpListener. Про то, как создать такой сервер я уже писал статью на Habr, с тех пор прошло не так много времени, тем не менее функционала стало больше, в том числе добавлен модуль, который позволяет запускать серверную часть в режиме фонового процесса и управлять им, а также он включает в себя большую часть используемых функций с возможностью удаленного взаимодействия с сервером для каждой команды, вывод которых будет одинаковый как для локальной, так и для удаленной машины. Все функции представляют из себя дополненный и более читаемый вывод уже встроенных WMI/CIM команд, результат которых можно получить с удаленный машины через данный модуль в PowerShell, или любой REST-клиент, например curl в Linux, без необходимости конфигурации WinRM или ssh.
Устанавливаем модуль и запускаем серверную часть на одной машине:
Install-Module ps.win.api -Repository NuGet -AllowClobber
Import-Module ps.win.api
Start-WinAPI
Test-WinAPI
Port Status
---- ------
8443 OpenНа удаленной машине предварительно устанавливаем модуль и используем функцию, например, для удаленного и локального просмотра датчиков температуры дисков:
Get-Smart
Get-Smart -ComputerName 192.168.3.100 -User rest -Pass api -Port 8443Пример вывода температуры датчиков на локальной и удаленной Windows машинах
Примеры работы и настройки можно найти в репозитории на GitHub. Также помимо запуска и остановки служб и процессов, добавлен функционал просмотра всех журналов событий Windows через Web-интерфейс с возможностью фильтрации вывода, пример для ssh подключений на скриншоте:
Get-Query
В системе Windows для просмотра в консоли списка текущих авторизованных пользователей, а также запущенных ими процессов присутствует встроенная программа query.exe, которая отдает вывод в текстовом формате. Модуль Get-Query преобразуя вывод команды в формат объекта, что позволяет использовать его для мониторинга активных пользовательских сессий, например, через активного Zabbix-агента, а также с помощью такого модуля (или любого другого подобного модуля в формате PSObject) можно заполнить таблицу DataGridView используемую в Windows Forms, данный подход я использовал в проекте RSA. Пример вывода для одного пользователя:
Install-Module Get-Query
Get-Query
User : lifailon
Session : console
ID : 1
Status : Active
IdleTime : отсутствует
LogonTime : 12.02.2024 13:08Итог
По мимо перечисленных модулей, присутствуют модули на мониторинга Veeam репозиториев и заданий, а так же датчиков температуры системы через Open и LibreHardwareMonitor, статью про последний я также писал на Habr, где упоминал про кастомизацию терминала, используя профили для oh-my-posh. Всего модулей в различных репозитория огромное множество, менеджер Nuget насчитывает больше 392 тысяч пакетов, 30 тысяч из которых составляют модули для PowerShell и библиотеки, которые могут быть интегрированы через платформу .NET. Использование удобных именно для вас модулей заставляет меньше покидать терминал, а времяпровождение в консоли приносит все больше удовольствия, и как мне кажется, формирует полезную привычку в дальнейшем.
Все привет! В уходящем году хочу оставить небольшой след про такой сильный язык программирования, как 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.
Но эту проблему можно исправить, используя классы .NET, например, System.Net.Sockets.TcpClient для проверки портов, где можно определить timeout ожидания ответа в 100мс и ситуация становится более наглядной, и демонстрирует разницу, при проверки одного порта на всех 254 хостах, создание заданий с использования ThreadJob занимает в среднем на 30-40% меньше времени, чем пауза (Start-Sleep) в 100 миллисекунд.
Сравнение метода BeginConnect с и без использования ThreadJob (timeout 100 milliseconds).
Управлять же заданиями максимально удобно, т.к. есть возможность отслеживать их статус, узнать состояние и время работы, читать вывод, ставить на паузу и даже отслеживать историю выполненных заданий.
Интерфейс последней версии RSA 1.4.1
Далее мне хотелось увеличить возможности удаленного администрирования без прямого взаимодействия с удаленным пользователем и добавить инструментов, за время работы у меня выработался определенный алгоритм, который я выполняю при анализе проблем в работоспособности операционной системы – это оценка нагрузки процессов, состояние служб, проверка 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.
Инструкции
Ниже приведены инструкции по использованию Windows PowerShell для управления объектами групповой политики Windows Active Directory.
- В приведенном ниже примере команды возвращаются все объектов групповой политики, найденные в указанном домене:
Get-GPO -All -Domain “TSDOMAIN.local”

- Get-GPO можно использовать для возврата общей информации для определенного объекта групповой политики. В примере ниже приведена общая информация для объекта групповой политики «Team_WP».
Get-GPO -Name Team_WP

- Информацию о объекте групповой политики можно вернуть, запросив идентификатор GUID объекта групповой политики. команда ниже приведена в качестве примера:
Get-GPO -Guid cb6fe78f-8b4f-4a77-9320-6a087a9d2bcc -Domain “TSDOMAIN.local”

- Команда Get-GPOReport ниже возвращает комплексный отчет для всех объектов групповой политики домена, компиляляя информацию в формате HTML для просмотра.
Get-GPOReport -All -Domain “TSDOMAIN.Local” -ReportType HTML -Path “C:\GPOReports\GPOReportsAll.html”

- После запуска Get-GPOReport файл HTML создается по пути к файлу, указанному в команде выше.

- Открываемые файлы будут отображаться как страница браузера со подробными сведениями о всех найденных объектов групповой политики домена.

Дополнительная информация
Уважаемые пользователи форума, помогите пожалуйста, со следующим вопросом.
Я пытаюсь создать приложение с графическим интерфейсом в Powershell. Так как я новичок в программировании, то решился обратиться на форум за помощью.
Суть приложения заключается в вводе названия автомобиля в $InputBox.text и последующим отображении эмблемы автомобиля в $PictureBox.
Папка, в которой будут находиться изображения эмблем автомобилей, будет содержать много изображений разного размера.
При этом я хочу, чтобы программа отображала изображение в $PictureBox строго заданного размера: ширина 200, высота 110.
Если изображение больше по ширине – 200 и высоте – 110, я хочу, чтобы программа сжала его до размеров ширина – 200 и высота – 110 и отобразила изображение в $PictureBox.
Если изображение меньше ширины – 200 и высоты – 110, я хочу, чтобы программа растянула его до размеров ширина – 200 и высота – 110 и отобразила изображение в $PictureBox.
На скриншоте ниже показано, как программа выглядит сейчас.
Заранее благодарю за помощь.
Add-Type -assembly System.Windows.Forms
$form = New-Object System.Windows.Forms.Form
$form.Size = New-Object System.Drawing.Size(500,500)
$form.Text = 'Сars'
############################################ Label ############################################
$Label = New-Object System.Windows.Forms.Label;
$Label.Text = "Cars emblem";
$Label.Location = New-Object System.Drawing.Point(280,30);
$Label.ForeColor = "#3009f1"
$Label.Font = "Microsoft Sans Serif,14"
$Label.AutoSize = $true;
$form.Controls.Add($Label);
$Label_2 = New-Object System.Windows.Forms.Label;
$Label_2.Text = "Cars name";
$Label_2.Location = New-Object System.Drawing.Point(10,10);
$Label_2.ForeColor = "#3009f1"
$Label_2.Font = "Microsoft Sans Serif,14"
$Label_2.AutoSize = $true;
$form.Controls.Add($Label_2);
############################################ InputBox #########################################
$InputBox = New-Object System.Windows.Forms.TextBox
$InputBox.Location = New-Object System.Drawing.Size(10,40)
$InputBox.Size = New-Object System.Drawing.Size(200,35)
$InputBox.Font = New-Object System.Drawing.Font("Lucida Sans Typewriter",18,[System.Drawing.FontStyle]::Regular)
$Form.Controls.Add($InputBox)
############################################ PictureBox ############################################
$PictureBox = New-Object System.Windows.Forms.PictureBox
$PictureBox.Location = New-Object System.Drawing.Point(270,70)
$PictureBox.size = New-Object System.Drawing.Size(200,110)
$PictureBox.BackColor = "#d2d2d2"
$form.Controls.add($PictureBox)
############################################ Function ############################################
function emblem {
$image = [System.Drawing.Image]::Fromfile('C:\cars\' + $InputBox.text + '.png')
$pictureBox.Image=$image
#$PictureBox.Load=$image
}
######################################################### Button #########################################################
$Button = New-Object System.Windows.Forms.Button
$Button.Location = New-Object System.Drawing.Size(10,90)
$Button.Size = New-Object System.Drawing.Size(110,80)
$Button.Text = "Display
picture"
$Button.BackColor = "#86bb6f"
$Button.Font = "Microsoft Sans Serif,14"
$Button.Add_Click({emblem})
$Form.Controls.Add($Button)
$form.ShowDialog() 
Windows PowerShell — программа, который объединяет в себе командную оболочку и среду для написания сценариев. Она базируется на .NET и предоставляет средства для управления компьютером и автоматизации рутинных задач. Платформа обладает функциональностью полноценного объектно-ориентированного языка, включая поддержку переменных, функций, классов и объектов.
В отличие от многих других командных оболочек, PowerShell при работе оперирует не строками, а объектами. Это позволяет разрабатывать и применять сложные логические конструкции. Важно отметить, что интерпретатор PowerShell полностью совместим со стандартными командами cmd.exe и способен выполнять их функции без ограничений.
Взаимодействие с командами осуществляется в интерактивном режиме внутри терминала. Однако, если требуется сохранить используемый скрипт, более удобным вариантом станет использование среды ISE.
Windows PowerShell ISE представляет собой интегрированное средство разработки сценариев для языка PowerShell. Здесь можно создавать, сохранять и запускать скрипты с выделением синтаксиса, автоматическим дополнением, справочником команд и инструментами отладки. PowerShell ISE является легаси-инструментом, специфичным для версий языка до 5.1 включительно. В более поздних версиях предпочтение отдается универсальным интегрированным средам разработки с плагинами.
С начала 2016 года язык получил кросс-платформенную поддержку. Теперь его можно применять не только в операционных системах Windows 7, 8, 10, и 11, но и на macOS (начиная с версии 10.13), а также на различных популярных дистрибутивах Linux (подробная информация о совместимых дистрибутивах доступна в официальной документации).
Как открыть PowerShell в Windows
Как правило, PowerShell уже установлен на вашем компьютере по умолчанию. Однако, если по какой-то причине его нет, вы можете воспользоваться инструкциями, предоставленными Microsoft. В дополнение, в официальной документации имеются подробные руководства по установке на macOS и Linux.
PowerShell является независимым от версии операционной системы инструментом и работает одинаково стабильно как на Windows 10, так и на Windows Server.
Существует два основных метода для запуска PowerShell или PowerShell ISE в системе Windows: через меню «Пуск» и с помощью приложения «Выполнить».
- Для того чтобы открыть PowerShell через меню «Пуск», пройдите к папке Windows PowerShell, откройте её и выберите необходимое приложение. В этой директории доступны как 32-разрядные версии (отмечены как x86 в скобках), так и 64-разрядные версии терминала и ISE.

- Чтобы запустить PowerShell через приложение «Выполнить», используйте комбинацию клавиш Win + R. Когда появится окно, введите
powershellилиpowershell ise(в зависимости от того, какое приложение вам нужно) и нажмите кнопку ОК.

Команды (командлеты) PowerShell
В языке программы PowerShell команды носят название командлеты (от английского «cmdlet»). Все они формируются с использованием шаблона «Глагол-Существительное», или «Действие-Объект». Например, Get-Services и Start-Process. Благодаря такой структуре, можно легко понять предназначение команды, даже если вы с ней ещё не работали ранее.
Синтаксис командлетов
После имени самого командлета следует указание параметров и их значений. Между всеми частями команды следует проставлять пробелы. Вот пример синтаксиса командлета, который позволяет перейти в директорию C:\:
Set-Location -LiteralPath C:\ -PassThru
Разберем его на составные части:
Set-Location— буквально «вызвать команду». Этот командлет позволяет выполнять указанный блок сценария.-LiteralPath C:\— здесь передаем блок сценария, в котором используется командаSet-Locationдля перехода в каталогC:\.-PassThru— по умолчанию командлетInvoke-Commandне возвращает результат выполнения. Этот параметр указывает на необходимость вывода информации о местоположении, в которое был выполнен переход с помощью командыSet-Location.

Важно отметить, что регистр букв в командах PowerShell не имеет значения. Таким образом, данную команду можно записать в виде заглавных букв, строчных букв или даже смешанного регистра, и она все равно будет выполняться:
sEt-loCATion -PATH c:\ -passthru
Когда в одной строке объединены несколько команд, они разделяются точкой с запятой .;
Иногда команда может быть слишком длинной. Для разделения на несколько строк можно использовать символ обратного апострофа ` в месте переноса. Новую строку можно создать, нажав Shift + Enter (для переноса строки ниже текущей) или Ctrl + Enter (для переноса строки выше текущей).
Разделим предыдущую команду:
Set-Location ` -LiteralPath C:\ ` -PassThru

Алиасы
В процессе работы с терминалом иногда может быть неудобно постоянно вводить полные названия командлетов. Именно поэтому у наиболее часто используемых командлетов существуют псевдонимы (алиасы) — их сокращенные варианты.
Чтобы получить список доступных алиасов, вы можете воспользоваться командой Get-Alias. Кроме того, данной команде также доступен псевдоним gal.

Чтобы получить список алиасов для конкретного командлета, вы можете использовать параметр -Definition. Пример:
Get-Alias -Definition Set-Location

Если вам нужно узнать полное название командлета по его алиасу, используйте параметр -Name. Этот параметр необязателен, так как он является аргументом по умолчанию.
# Оба следующих варианта эквивалентны: Get-Alias -Name clear Get-Alias clear

Особенности обработки путей к каталогам
Для многих командлетов необходимо предоставить путь к файлу или каталогу. Это делается с использованием строки, например: C:\Windows\System32.
Однако, если в пути встречается пробел или другой специальный символ, PowerShell будет рассматривать его как разделитель. Например:
# Следующая команда не будет выполнена корректно Set-Location C:\Program Files

PowerShell «воспринимает» пробел и интерпретирует его так, будто путь к папке закончился на слове Program, а files — это уже значение другого параметра.
Чтобы избежать подобных ситуаций, существует два метода:
- Экранировать символы с помощью обратного апострофа
`:C:\Program` Files. Однако это может быть неудобным, если путь длинный. - Поместить весь путь в одинарные или двойные кавычки:
'C:\Program Files'или"C:\Program Files"(желательнее использовать одинарные кавычки).
Кроме того, в PowerShell существуют сокращения для быстрого доступа к ближайшим директориям:
- Точка
.указывает на текущий каталог. Например,Get-ChildItem .позволяет просмотреть содержимое текущего местоположения. - Две точки
..указывают на родительский каталог. Например,Set-Location ..позволяет перейти к родительскому каталогу. Это может быть полезно, если вы находитесь в глубоко вложенной директории.
Большинство командлетов имеют параметры -Path и -LiteralPath, позволяющие указать путь к файлу или папке. Разница между ними заключается в том, что в -Path можно включать переменные, в то время как —LiteralPath интерпретирует символы буквально, даже если они содержат имя переменной.
Get-Help: как изучать новые командлеты
Для получения подробной информации о конкретном командлете воспользуйтесь командой Get-Help Название-Командлета. Пример:
Get-Help Get-Childitem

У команды Get-Help имеется несколько полезных параметров:
-Detailedпредоставляет более подробную справку по командлету.-Fullпредоставляет полную справку.-Examplesдемонстрирует примеры использования командлета.-Onlineперенаправляет пользователя на веб-страницу с соответствующей документацией.
Объекты и конвейеры (пайплайны) в PowerShell
Когда вы работаете с командлетами в PowerShell, они возвращают не просто строки, а объекты — структуры данных, содержащие набор свойств и методов.
То, что отображается в терминале после выполнения команды в виде строки, на самом деле является визуальным представлением объекта. Программа PowerShell отображает определенные свойства объектов в виде таблицы, но далеко не все свойства могут быть отображены таким образом.
Аналогично тому, как командлеты могут возвращать объекты, они также могут принимать и обрабатывать их. Вы можете создать команду, которая возвращает объект, передать этот объект другому командлету, получить объект из него и так далее — этот процесс и называется конвейерами или пайплайнами.
Пример работы конвейера в PowerShell
Команда Get-Process возвращает список запущенных процессов на компьютере. При передаче ей имени процесса (или шаблона, созданного с помощью регулярных выражений), команда выведет только соответствующие элементы списка.
Рассмотрим пример, где вызываем запущенный процесс PowerShell:
Get-Process powershell

Мы получаем объект и таблицу, отображающую некоторые его свойства. Чтобы узнать все свойства и методы, давайте передадим этот объект командлету Get-Member. Для этого используется конвейер:
Get-Process powershell | Get-Member

Команда Get-Member получает объект от команды Get-Process и выводит таблицу со всеми его свойствами и методами. Результат работы Get-Member также представляет собой объект (точнее, список объектов), который можно передать по конвейеру дальше.
Допустим, нужно вывести только те строки, в которых MemberType равно Property. Для этого используем команду Where-Object:
Get-Process powershell | Get-Member | Where-Object {$_.MemberType -eq 'Property'}
Команда Where-Object последовательно обходит каждый объект, полученный от команды Get-Member. Выражение в фигурных скобках — логическое:
$_ссылается на текущий объект (то есть на отдельную строку в таблице);.MemberTypeобращается к значению свойстваMemberTypeв этом объекте;-eqвыполняет сравнение между выражением слева и выражением справа от него;'Property'представляет значение, которое ожидаем увидеть у свойстваMemberType.
Более подробно о логических выражениях рассказано ниже.
Форматирование таблиц с помощью конвейеров
Командлет Format-Table в PowerShell предоставляет возможность настроить вывод таблицы в терминале: выбирать нужные свойства и методы, устанавливать ширину столбцов, группировать данные по нескольким таблицам и т. д.
Форматируем таблицу, полученную с помощью командлета Get-Member. Следует использовать следующий синтаксис:
Get-Process powershell | Get-Member | Format-Table -AutoSize -Wrap -GroupBy MemberType -Property Name, Definition

Разберем параметры командлета Format-Table:
-AutoSizeвыравнивает ширину столбцов в соответствии с размерами их содержимого. Это позволяет оптимально использовать ширину экрана.-Wrapпереносит содержимое ячейки на новую строку, если оно не помещается в текущих размерах экрана. По умолчанию, если текст не помещается, он обрезается.-GroupByпозволяет разделить одну таблицу на несколько, сгруппированных по значению определенного свойства. В данном случае, для каждого значенияMemberTypeбудет создана отдельная таблица.-Propertyопределяет, какие свойства объекта будут отображены в таблице в качестве столбцов. В данном примере, мы указали свойстваNameиDefinition.
Эти параметры позволяют настраивать внешний вид таблицы, сделать вывод более читабельным и структурированным.
Сортировка таблиц с помощью конвейеров
Командлет Sort-Object в PowerShell позволяет сортировать список объектов (таблицу) по значениям их свойств (столбцов). Давайте отсортируем результат, полученный с помощью командлета Get-Member, по столбцу Name в алфавитном порядке. Для этого воспользуемся параметром -Property, который действует аналогично параметру у командлета Format-Table:
Get-Process powershell | Get-Member | Sort-Object -Property Name

Командлет Sort-Object в PowerShell имеет также другие полезные параметры:
-Descendingсортирует объекты в порядке убывания. Например:
Get-Process powershell | Get-Member | Sort-Object -Property Name -Descending
-Uniqueудаляет дубликаты и возвращает только уникальные объекты. Например:
Get-Process powershell | Get-Member | Sort-Object -Property Name -Unique
- Параметр
-Topполучает число N и отображает первые N объектов в таблице. Например:
Get-Process | Sort-Object -Property CPU -Top 10
- Параметр
-Bottomполучает число N и отображает последние N объектов в таблице. Например:
Get-Process | Sort-Object -Property Memory -Descending -Bottom 5
Эти параметры позволяют более гибко настраивать сортировку и отображение объектов в выводе.
Фоновое выполнение команд
Определенные задачи могут требовать значительного времени на выполнение. Примеры таких задач включают установку и обновление программного обеспечения или поиск файлов в обширной директории. Важно помнить, что во время выполнения одной команды в PowerShell нельзя вводить другие команды.
Рассмотрим пример: предположим, нужно найти файл powershell.exe на всем диске C. Для этой цели воспользуемся командлетом Get-ChildItem с параметром -Recurse. Это позволит ему искать файл не только в текущем каталоге, но и во всех его подкаталогах.
Следует учитывать, что PowerShell может столкнуться с папками, к которым у него нет доступа. Чтобы обойти возможные ошибки, добавим параметр -ErrorAction SilentlyContinue. Это означает, что в случае ошибки команда не будет генерировать уведомления, а просто продолжит выполнение.
Таким образом, данная ситуация выглядит следующим образом:
Get-ChildItem -Path C:\ -Name powershell.exe -Recurse -ErrorAction SilentlyContinue

Очевидно, что во время выполнения задачи, командная строка становится недоступной. Для принудительного прерывания выполнения задачи можно воспользоваться сочетанием клавиш Ctrl + C. Важно убедиться, что при этом ничего не выделено, чтобы избежать возможного восприятия компьютером как команды «Копировать».
Start-Job {Get-ChildItem -Path C:\ -Name powershell.exe -Recurse -ErrorAction SilentlyContinue}
Параллельно возможно выполнение любого числа фоновых задач. В дополнение к командлету Start-Job, предназначенному для управления фоновыми задачами, существуют и другие командлеты:
Get-Jobпредоставляет отчет о состоянии фоновых задач.Wait-Jobблокирует консоль до завершения фоновой задачи.Stop-Jobпрекращает выполнение фоновой задачи.Receive-Jobвыводит результаты выполнения фоновой задачи и очищает их из памяти. Для сохранения результатов в памяти используйте параметр-Keep.
Опции Wait-Job, Stop-Job и Receive-Job требуют указания имени Name или идентификатора Id конкретной задачи или задач (в случае нескольких). Это можно сделать непосредственно или в связке с командлетом Get-Job.
Get-Job Job1

Работа с файлами
PowerShell предоставляет удобные средства для работы с файлами. Вот некоторые ключевые методы:
Для создания файла используйте командлет New-Item с указанием пути к файлу:
New-Item -Path "C:\путь\к\файлу\новыйфайл.txt" -ItemType File
Чтобы записать данные в файл, используйте Out-File или Set-Content:
"Содержимое файла" | Out-File -FilePath "C:\путь\к\файлу\новыйфайл.txt" Set-Content -Path "C:\путь\к\файлу\новыйфайл.txt" -Value "Новое содержимое файла"
Для чтения содержимого файла в массив используйте Get-Content:
$содержимое = Get-Content -Path "C:\путь\к\файлу\новыйфайл.txt"
Для получения информации о файле (размер, дата создания и др.) используйте Get-Item:
$информацияОФайле = Get-Item -Path "C:\путь\к\файлу\новыйфайл.txt"
Для копирования файла в другое место используйте Copy-Item:
Copy-Item -Path "C:\путь\к\файлу\новыйфайл.txt" -Destination "C:\путь\к\копия\новыйфайл.txt"
Для удаления файла воспользуйтесь командлетом Remove-Item:
Remove-Item -Path "C:\путь\к\файлу\новыйфайл.txt" -Force
Помните, что операции удаления файлов необратимы, поэтому будьте осторожны при их использовании.


