Привет, Хабр!
Меня зовут Денис, я ведущий специалист в отделе информационной безопасности компании «Совкомбанк Технологии». Наша команда занимается поддержкой работы антивируса, программ для сбора логов на конечных точках и другими задачами в области ИБ.
В каждой ИТ-команде рано или поздно появляется свой набор скриптов, и у каждого сотрудника он может быть индивидуальный: у кого-то — волшебный .ps1-файл для быстрого развёртывания или сбора информации из сети, у кого-то — личная палочка-выручалочка для генерации отчётов. Наша команда не стала исключением. Были и общие скрипты, и личные «шедевры», передаваемые из рук в руки. Эти инструменты экономили часы работы — но только для тех, кто знал, какие параметры подавать на вход скрипта, где лежит актуальная версия скрипта и так далее. Стало ясно, что необходимо объединить их для более эффективного выполнения рутинных задач, и этим решением стал GUI, о чём мы поговорим в статье.
Это руководство пригодится всем, кто устал от рутины и хочет сделать свои PowerShell-скрипты доступными для коллег: системным администраторам, инженерам технической поддержки, DevOps-специалистам.
Мы не только разберем основы создания кнопок и окон, но и ответим на ключевые вопросы: Как выбрать между WinForms и WPF, как избежать зависания интерфейса при выполнении долгих операций, и как удобно упаковать ваш скрипт в EXE или ярлык, чтобы любой сотрудник мог запустить его одним кликом.
Графический интерфейс как решение
Переломный момент наступил, когда я задал себе вопрос: «Почему скрипт обязательно должен быть в консоли?». Почему бы не превратить его в удобное приложение с кнопками, подсказками и прогресс-барами, которое будет понятно каждому? Я начал внедрять графические интерфейсы на PowerShell — и это изменило всё. Скрипты перестали быть «чёрными ящиками», доступными только избранным. Они стали инструментами команды: обновляемыми, надёжными и интуитивно понятными. И каждый может ими воспользоваться — просто нажав кнопку.
Windows Forms или WPF: какой интерфейс выбрать и когда?
Для реализации графического интерфейса GUI в PowerShell доступны два основных подхода:
Windows Forms — проверенная, но уже устаревшая технология, главное преимущество которой — простота использования.
WPF — более современное и гибкое решение, позволяющее создавать продвинутые интерфейсы, но требующее изучения основ.
Сравнительная таблица
Критерий |
Windows Forms |
WPF |
Сложность |
Прост в освоении, минимальный порог входа |
Требует изучения XAML и новых концепций |
Современность |
Устаревшая технология |
Актуальная, поддерживает современные стандарты |
Дизайн |
Устаревший, но функциональный |
Современный, с анимациями |
Поддержка |
Работает даже на Windows 7 |
Требует .NET 3.0+ |
Гибкость |
Ограниченная кастомизация |
Полный контроль над интерфейсом |
Быстрый старт: PowerShell + GUI
Windows Forms
Add-Type -AssemblyName System.Windows.Forms
# Создаем форму
$form = New-Object System.Windows.Forms.Form
$form.Text = "Пример WinForms"
$form.Size = New-Object System.Drawing.Size(300, 200)
# Добавляем кнопку
$button = New-Object System.Windows.Forms.Button
$button.Text = "Нажми меня"
$button.Location = New-Object System.Drawing.Point(100, 50)
$button.Add_Click({ [System.Windows.Forms.MessageBox]::Show("Привет, WinForms!") })
# Добавляем элементы на форму
$form.Controls.Add($button)
# Показываем форму
$form.ShowDialog() | Out-Null

WPF (без XAML)
Add-Type -AssemblyName PresentationFramework
# Создаем окно
$window = New-Object System.Windows.Window
$window.Title = "Пример WPF"
$window.Width = 300
$window.Height = 200
# Создаем кнопку
$button = New-Object System.Windows.Controls.Button
$button.Content = "Нажми меня"
$button.Add_Click({ [System.Windows.MessageBox]::Show("Привет, WPF!") })
# Добавляем кнопку в окно
$window.Content = $button
# Показываем окно
$window.ShowDialog() | Out-Null

WPF с XAML (рекомендуется для сложных интерфейсов)
Add-Type -AssemblyName PresentationCore, PresentationFramework
# XAML-разметка (у кнопки есть имя "MyButton")
$xaml = @"
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="WPF с XAML" Width="300" Height="200">
<Button x:Name="MyButton" Content="Нажми меня" HorizontalAlignment="Center" VerticalAlignment="Center" />
</Window>
"@
# Загружаем XAML
$reader = [System.Xml.XmlReader]::Create([System.IO.StringReader]::new($xaml))
$window = [Windows.Markup.XamlReader]::Load($reader)
# Находим кнопку по имени и добавляем действие
$button = $window.FindName("MyButton")
$button.Add_Click({ [System.Windows.MessageBox]::Show("XAML работает!", "Успех") })
# Показываем окно
$window.ShowDialog() | Out-Null

Оптимизация работы скриптов: как избежать зависания интерфейса
Когда в графическом интерфейсе запускаются ресурсоёмкие скрипты, интерфейс может перестать реагировать. Это происходит потому, что основной поток занят вычислениями и не обрабатывает действия пользователя.
Решение: фоновые задачи с Start-ThreadJob
Командлет Start-ThreadJob позволяет выполнять скрипты в отдельном потоке, сохраняя отзывчивость интерфейса.
Пример для WPF:
Add-Type -AssemblyName PresentationFramework
Add-Type -AssemblyName WindowsBase
# Создаем окно в XAML
[xml]$xaml = @"
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
Title="Фоновая задача в WPF" Height="200" Width="300">
<StackPanel VerticalAlignment="Center">
<ProgressBar Name="ProgressBar" Height="20" Margin="10" Minimum="0" Maximum="100"/>
<Button Name="StartButton" Content="Запустить задачу" Margin="10"/>
</StackPanel>
</Window>
"@
# Загружаем XAML
$reader = [System.Xml.XmlNodeReader]::new($xaml)
$window = [Windows.Markup.XamlReader]::Load($reader)
$progressBar = $window.FindName("ProgressBar")
$startButton = $window.FindName("StartButton")
# Запуск фоновой задачи
$startButton.Add_Click({
Start-ThreadJob -ScriptBlock {
$window = $using:window
$progressBar = $using:progressBar
foreach($i in 1..100 ){
if($i -eq 50){
$window.Dispatcher.Invoke([action]{
$progressBar.Value = $i
},"Normal")
}
if($i -eq 100){
$window.Dispatcher.Invoke([action]{
$progressBar.Value = $i
},"Normal")
}
}
}
})
$window.ShowDialog()

Примечание:
Start-ThreadJob — доступен только в PowerShell 7+. Для версий 5.1 и ниже используйте Runspaces или комбинацию Register-ObjectEvent с Start-Job.
Оптимальные способы запуска PowerShell-скриптов
При распространении скриптов внутри компании всегда важно не забывать о цифровой подписи скриптов,если политики безопасности это требуют.
Для удобства пользователей можно выбрать один из двух подходов:
Конвертация PS1 в EXE (с помощью PS2EXE)
Install-Module -Name ps2exe -Force
Invoke-PS2EXE-InputFile"ваш_скрипт.ps1"-OutputFile"приложение.exe"-NoConsole-IconFile"иконка.ico"
Плюсы:
Автономность – не требует PowerShell вручную
Защита кода – но не полная
Минусы:
- Антивирусы могут блокировать такие EXE-файлы.
2. Создание ярлыка
Плюсы:
Простота и быстрое обновление.
Не требует пересборки при изменениях скрипта.
Как настроить:
Создайте ярлык.
-
В поле «Расположение объекта» укажите:
powershell.exe -ExecutionPolicy Bypass -WindowStyle Hidden –File "путь к скрипту " Добавьте иконку через свойства ярлыка.
Заключение
PowerShell — это не просто командная строка, а мощный инструмент для создания удобных и функциональных интерфейсов. С его помощью можно:
Превращать сложные скрипты в простые приложения.
Интегрироваться с API и внутренними системами.
Автоматизировать рутину, экономя часы работы.
Главный результат? Раньше наши скрипты напоминали священные свитки — ценные, но доступные лишь избранным. Теперь это рабочие инструменты, которые:
Ломают барьеры между разработчиками и пользователями.
Синхронизируют команду (никаких «у меня другая версия»).
Превращают сложное в простое.
По факту, мы не просто автоматизировали процессы — мы изменили культуру работы.
А как у вас? Объединяет ли автоматизация вашу команду или, наоборот, создаёт барьеры?
Совет: Начните с одной задачи, добейтесь успеха — и масштабируйте решение. PowerShell GUI тем и хорош, что растёт вместе с вашими потребностями.
Удачи в автоматизации!
Andrei9385
Раньше тоже писал формы на Powershell, Windows Forms и WPF, потом стал писать с ИИ на IIS, с доступом через вэб интерфейс. ИИ успешно с этим справляется, доступ ко всем сервисам из одной точки, Kerberos аутентификация. Это более универсальный метод и формы можно красивые и гибкие делать.