Навигация по странице
Для оповещения пользователей о различных событиях, вы можете выводить различные графические уведомления из скриптов PowerShell. В PowerShell можно использовать всплывающие уведомления в трее Windows или модальные окно для получения информации от пользователя или подтверждения действия.
Для эффективной работы любой операционной системы необходимо вести мониторинг ее состояния, для того, чтобы своевременно выявлять проблемы и узкие места в производительности. Еще лучше лучше, когда такой мониторинг ведется в автоматическом режиме, с помощью скриптов.
В операционных системах семейства Windows для автоматизации выполнения задач мониторинга лучше всего использовать Powershell. И далее в этой статье мы рассмотрим несколько полезных скриптов, которые могут упростить мониторинг состояния различных компонентов ОС.
Начнем с мониторинга состояния сетевых портов и взаимодействующих с ними процессов.
С помощью PowerShell вы можете получать, добавлять, удалять, или изменять значения переменных окружения (среды). В переменных окружения Windows хранит различную пользовательскую и системную информацию (чаще всего это пути к системным и временным папкам), которая используется операционной системой и приложениями, установленными на компьютере.
В Windows доступны несколько типов переменных окружения:
- Переменные окружения процесса – создаются динамически и доступны только в текущем запущенном процесс
- Пользовательские переменные окружения – содержат настройки конкретного пользователя и хранятся в его профиле (хранятся в ветке реестре
HKEY_CURRENT_USER\Environment
) - Системные переменные окружения – глобальные переменные окружения, которые применяются для все пользователей (хранятся в ветке
HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment
)
Типы переменных окружения Windows указаны в порядке уменьшения приоритета. Т.е. значение переменной окружения %TEMP% в пользовательском профиле будет иметь больший приоритет, чем значение системной переменной окружения %TEMP%.
Для управления переменными окружениями обычно используется вкладка Advanced в свойствах системы. Чтобы открыть System Properties, выполните команду
SystemPropertiesAdvanced
и нажмите на кнопку Environment Variable.
В этом окне можно создать и отредактировать переменные среды для текущего пользователя или системные переменные окружения.

Чтобы вывести полный список переменных окружения и их значения в PowerShell, выполните команду:

Как вы видите, для доступа к переменным окружения в PowerShell используется отдельный виртуальный диск Env:, доступный через провайдер Environment.

Получить значение определенной переменной окружения Path:

Т.к. переменные окружения, по сути, это файлы на виртуальном диске, нажатием кнопки TAB вы можете использовать автозавершение для набора имени переменной окружения.

Чтобы разбить значение переменной окружения на строки, выполните:
(Get-ChildItem env:Path).value -split ";"

Добавить значение в переменную окружения Path:
$Env:Path += ";c:\tools"
Однако это добавляет временное значение в переменную окружения
Path
. При следующей перезагрузке новое значение в переменной будет сброшено. Чтобы добавить постоянное значение в системную переменную окружения, используется такая конструкция:
Несмотря на то, что фактически переменные окружения и их значения хранятся в реестре, прямое изменение их значений в реестре используется редко. Причина в том, что текущий процесс при запуске считывает значение переменных окружения из реестра. Если вы измените их, процесс не будет уведомлён об этом.
Если вам нужно из PowerShell изменить в реестре значение переменной окружения, используются команды:
$variable = Get-ItemPropertyValue -Path 'HKCU:\Environment\' -Name 'Path'
$add_path = $variable + ';C:\Git\'
Set-ItemProperty -Path 'HKCU:\Environment\' -Name 'Path' -Value $add_path
Вы можете создать локальную переменную окружения. По умолчанию такая переменная окружения будет доступна только в текущем процессе (PowerShell), из которого она создана. После того, как процесс будет закрыт – переменная окружения будет удалена.
$env:SiteName = 'winitpro.ru'
Get-ChildItem Env:SiteName
Если нужно создать глобальную системную переменную (нужны права администратора), используйте команду:
Очистить и удалить глобальную переменную окружения:
Все привет! В уходящем году хочу оставить небольшой след про такой сильный язык программирования, как 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.
Какое расширение имеют файлы скриптов PowerShell
PowerShell-скрипты имеют расширение *.ps1*, и для их выполнения часто требуется предварительная настройка политики выполнения скриптов (Execution Policy), чтобы разрешить запуск скрипта через PowerShell в системе.
Про заряд
Но отвлечемся от темы безопасности и посмотрим еще один интересный скрипт для мониторинга заряда батареи на ноутбуке. Основный принцип, на котором основан мониторинг довольно прост, сначала мы запускаем команду для проверки каждой батареи в системе. Далее мы добавляем полученные данные к объекту, содержащему отчетную информацию о батарее, сколько заряда у нее должно быть, по данным производителя, сколько заряда она на самом деле держит, информацию о производителе и некоторые идентифицирующие свойства.
$AlertPercent = "70"
& powercfg /batteryreport /XML /OUTPUT "batteryreport.xml"
Start-Sleep 1
[xml]$Report = Get-Content "batteryreport.xml"
$BatteryStatus = $Report.BatteryReport.Batteries |
ForEach-Object {
[PSCustomObject]@{
DesignCapacity = $_.Battery.DesignCapacity
FullChargeCapacity = $_.Battery.FullChargeCapacity
CycleCount = $_.Battery.CycleCount
Id = $_.Battery.id
}
}
if (!$BatteryStatus) {
Write-Host "This device does not have batteries, or we could not find the status of the batteries."
}
foreach ($Battery in $BatteryStatus) {
if ([int64]$Battery.FullChargeCapacity \* 100 [int64]$Battery.DesignCapacity -lt $AlertPercent) {
Write-host "The battery health is less than expect. The battery was designed for $($battery.DesignCapacity) but the maximum charge is $($Battery.FullChargeCapacity). The battery info is $($Battery.id)"
}
}Стоит отметить, что этот скрипт был протестирован на ряде устройств, но, конечно, некоторые устройства могут не обнаруживать заряд батареи, или просто не сообщают о своей системе заряда. В этом случае скрипт просто выводит на консоль соответствующее сообщение.
Bat-скрипты Windows
Bat-скрипты, или файлы пакетных команд (Batch-файлы), представляют собой текстовые файлы, содержащие команды и инструкции для выполнения в командной строке Windows. Основаны на языке пакетных команд (Batch scripting language). Расширение файла: *.bat* (например, *myscript.bat*).
Пример простого bat-скрипта:
Выполнение скриптов в PowerShell
PowerShell представляет собой новую командную оболочку для операционной системы Windows, созданную Microsoft с целью полного замещения и улучшения cmd. Эта оболочка уже включена в состав операционных систем Windows 7 и выше. Если у вас старая версия операционной системы или вы хотите загрузить более новую версию PowerShell. Windows — операционная система, пользующаяся огромной популярностью среди миллионов пользователей по всему миру. В ее арсенале множество функций и возможностей, однако некоторые из них остаются недостаточно известными обычным пользователям. В данной статье мы расскажем о нескольких полезных сценариях, способных сделать вашу работу с Windows более эффективной и удобной.
Политика исполнения PowerShell-скриптов представляет собой механизм безопасности, управляющий условиями загрузки конфигурационных файлов и запуска сценариев в данной среде. Её основное предназначение — предотвращение выполнения потенциально вредоносных сценариев.
Полезные сценарии для Windows
1. Скрипт выключения Windows (или перезагрузки):
Простейшая операция выключения компьютера. Откройте блокнот и введите:
shutdown -s -t 0
Сохраните файл с расширением *.cmd* (например, *shutdown.cmd*). При запуске этого файла компьютер выключится. Замените «-s» на «-r» для перезагрузки. Параметр «-t» устанавливает таймер; в данном случае, он равен 0 секунд, но можно установить, например, на 60 для выключения через 60 секунд.
2. Удаление ненужных приложений:
С помощью следующего скрипта можно удалить предустановленные приложения:
Замените *APPNAME* на название ненужного приложения. Хотя удаление можно выполнить стандартным способом или через программы, этот скрипт делает процесс более удобным.
3. Управление процессами:
Воспользуйтесь PowerShell для борьбы с медленными процессами. Выведите все службы:
Или получите информацию о конкретной службе с кодовым именем *NAME*:
Создайте файл, который закрывает процессы с повышенным потреблением ресурсов:
Stop-Service -Name *ANTIVIRUS*
Stop-Service -Name *BROWSER*
Замените *ANTIVIRUS* и *BROWSER* на соответствующие названия.
4. Переименование группы файлов:
Решите проблему однотипных файлов с помощью скрипта группового переименования:
$path = «$comp\desktop\journey\russia»
$filter = ‘*.jpg’
Укажите путь, расширение и выполните замены в строке.
5. Поиск файлов:
Используйте PowerShell для поиска файлов в директории:
Для более сложного поиска в подпапках:
Get-ChildItem C:\Windows\* -Include *.log -Recurse -Force
6. Справка:
Пользуйтесь командой *Get-Help* для получения информации:
Для более подробной справки по конкретной команде:
Get-Help —Name *CMDLET*
7. Получение информации о системе:
Используйте PowerShell для получения данных о системе, например, уровне заряда аккумулятора:
Add-Type -AssemblyName System.Windows.Forms
Информация об архитектуре процессора удаленного компьютера:
Проверка прав администратора текущего пользователя:
Эти простые и полезные сценарии помогут вам эффективнее управлять вашей системой Windows.
Про сети
Типичная история – это использование одного порта несколькими процессами. Ну, точнее попытки использования, так как, естественно порт займет первый процесс, а все остальные уже не смогут это сделать.
Приведенный скрипт достаточно многофункционален, то есть, вы можете настроить его на оповещение об измененных слушателях порта, вы можете настроить его на оповещение о конкретном слушателе, которого вы ожидаете там увидеть, или вы можете оповещать о приложениях, которые не должны прослушиваться.
В приведенном ниже примере, в переменной $ExpectedApplication мы определяем процесс, который мы ожидаем увидеть в списке слушающих порты, $NotAllowedApplication это соответственно тот процесс, который мы не хотим видеть в списке слушателей. Здесь Teamviewer это как раз то самое нежелательное приложение.
Результат работы скрипта представляется сообщениями со статусами Healthy/Unhealthy и соответствующей информацией. Так отсутствие процесса из $ExpectedApplication это Unhealthy, а отсутствие $NotAllowedApplication это наоборот Healthy.
$ExpectedApplication = "svchost"
$NotAllowedApplication = "Teamviewer"
$CompareToPrevious = $true
$Connections = Get-NetTCPConnection | Where-Object { $_.LocalAddress -eq "0.0.0.0" -and $_.State -eq "Listen" }
$Processes = Get-Process
$CurrentListeners = foreach ($Connection in $Connections) { [PSCustomObject]@{
Process = ($Processes | Where-Object id -eq $Connection.OwningProcess).Name
Port = ($Connection.LocalPort)
Path = ($Processes | Where-Object id -eq $Connection.OwningProcess).Path
}
}
if ($ExpectedApplication -notin $CurrentListeners.Process) {
write-host "Unhealthy - The expected application was not found in the current process list"
} else {
write-host "Healthy - The expected application was found in the current process list"
}
if ($NotAllowedApplication -in $CurrentListeners.Process) {
write-host "Unhealthy - The non-allowed application was found in the current process list"
} else {
write-host "Healthy - The non-allowed application was not found in the current process list"
}
if ($CompareToPrevious -eq $true) {
$PreviousResult = Get-content -Path "C:\ProgramData\ListenerMonitor.txt" | ConvertFrom-Json
$Result = Compare-Object $CurrentListeners $PreviousResult -Property Process,Port,Path
if ($Result) {
write-host "Unhealthy - The Listener list has changed."
$Result
} else {
write-host "Healthy - The Listener list is still the same."
}
$CurrentListeners | ConvertTo-Json |out-file "C:\ProgramData\ListenerMonitor.txt"
}Результаты выполнения скрипта сохраняются в текстовом файле C:\ProgramData\ListenerMonitor.txt и при каждом следующем запуске мы сравниваем текущий список процессов с предыдущим, полагая, что сохраненный список является правильным. В файле хранится название процесса, номер порта и путь к файлу.
На основе этого сценария можно разработать собственные средства анализа состояния процессов и портов для того, чтобы с помощью этого скрипта мониторить не только сетевую активность процессов, но и безопасность системы в целом.
Скрипты PowerShell для администратора
PowerShell — мощный инструмент для сисадминов Windows, предоставляя широкий набор команд и сценариев для автоматизации и управления системой. Ниже приведены несколько примеров PowerShell-скриптов, которые могут быть полезны администраторам:
1. Создание резервной копии файлов:
$sourcePath = «C:\Path\To\Source»
$destinationPath = «D:\Backup»
$timestamp = Get-Date -Format «yyyyMMddHHmmss»
$backupFolder = «$destinationPath\Backup_$timestamp»
Copy-Item -Path $sourcePath -Destination $backupFolder -Recurse
2. Мониторинг дискового пространства:
$threshold = 80
$diskLetter = $disk.DeviceID
Write-Host «Warning: Disk $diskLetter is running low on free space ($freeSpacePercentage%)»
# Можно добавить уведомление администратора
3. Создание нового пользователя:
$password = ConvertTo-SecureString «SecurePassword123» -AsPlainText -Force
4. Мониторинг событий в журнале событий:
$logName = «System»
$events = Get-WinEvent -LogName $logName -MaxEvents 10
Write-Host «Event ID $($event.Id): $($event.Message)»
5. Обновление всех установленных модулей PowerShell:
Update-Module -Name $_.Name -Force
6. Удаление временных файлов в системной директории:
Remove-Item «$tempPath\*» -Force
7. Создание отчета о состоянии служб:
8. Настройка правил брандмауэра:
New-NetFirewallRule -DisplayName «Allow-SSH» -Direction Inbound -Protocol TCP -LocalPort 22 -Action Allow
9. Удаление неиспользуемых профилей пользователей:
$inactiveDays = 90
$lastUseDate = $profile.LastUseTime
$difference = (Get-Date) — $lastUseDate
Remove-WmiObject -InputObject $profile -Confirm:$false
Эти примеры предоставляют общее представление о том, как PowerShell может использоваться администраторами для автоматизации различных задач в Windows-среде. Помните, что некоторые команды могут потребовать выполнения от имени администратора.
Для вызова скриптов PowerShell, вы можете использовать команду `Invoke-Expression` или просто указать путь к файлу скрипта. Предположим, у вас есть следующие скрипты: `ClearDisk.ps1`, `InstallPrograms.ps1`, `BackupScript.ps1`, и `UpdateSystem.ps1`.
1. Скрипт очистки диска (ClearDisk.ps1):
# Ваш код для очистки диска
# Пример: удаление временных файлов
Remove-Item -Path «$env:TEMP\*» -Recurse -Force
# Используйте Invoke-Expression
Invoke-Expression -Command «.\ClearDisk.ps1»
# Или просто указывайте путь к файлу скрипта
2. Скрипт автоматической установки программ (InstallPrograms.ps1):
# Ваш код для автоматической установки программ
# Пример: установка программы Chocolatey и установка пакетов
Set-ExecutionPolicy Bypass -Scope Process -Force; iex ((New-Object System.Net.WebClient).DownloadString(‘https://chocolatey.org/install.ps1’))
choco install packageName -y
# Используйте Invoke-Expression
Invoke-Expression -Command «.\InstallPrograms.ps1»
# Или просто указывайте путь к файлу скрипта
3. Скрипт резервного копирования (BackupScript.ps1):
# Ваш код для создания резервной копии
# Пример: копирование файлов в другую директорию
$sourcePath = «C:\Path\To\Source»
$destinationPath = «D:\Backup»
Copy-Item -Path $sourcePath -Destination $destinationPath -Recurse
# Используйте Invoke-Expression
Invoke-Expression -Command «.\BackupScript.ps1»
# Или просто указывайте путь к файлу скрипта
4. Скрипт автоматического обновления системы (UpdateSystem.ps1):
# Ваш код для автоматического обновления системы
# Пример: обновление всех установленных модулей PowerShell
Update-Module -Name $_.Name -Force
# Используйте Invoke-Expression
Invoke-Expression -Command «.\UpdateSystem.ps1»
# Или просто указывайте путь к файлу скрипта
Убедитесь, что вы находитесь в той же директории, что и ваши скрипты, или укажите полный путь к файлу скрипта.
В этой статье мы коснулись всех аспектов создания, запуска и использования скриптов в Windows. Надеемся, что эти советы и примеры помогут вам освоить этот увлекательный мир автоматизации и сделают вашу работу более эффективной и приятной.
Отправка сообщения пользователю на удаленный компьютер
С помощью PowerShell вы можете отправить всплывающее сообщение пользователю на удаленный компьютер. Сначала нужно получить список сессии пользователей на удаленном компьютере (в случае RDS сервера):

Чтобы отправить сообщение в сессию пользователя на удаленном компьютер, выполните команду:
MSG kbuldogov /server:rds1 "Сервер будет перезагружен через 10 минут. Закройте документы"
Если всплывающее сообщение нужно отправить всем пользователям укажите * вместо имени пользователя:
MSG * /server:rds1 "Срочное сообщение всем! "

Для отправки всплывающего графического уведомления на удаленный компьютер можно воспользоваться скриптом RemoteSendToasNotification.ps1 из нашего GitHub репозитория ( https://github.com/winadm/posh/blob/master/scripts/RemoteSendToasNotification.ps1). Для подключения к удаленному компьютеру используется командлет Invoke-Command, который использует WinRM.

Как запустить скрипт через PowerShell с параметрами?
Запуск осуществляется аналогично запуску обычной программы или bat-файла с параметрами. Например, чтобы запустить скрипт с параметрами из командной строки, используйте следующую команду:
PowerShell -executionpolicy RemoteSigned -file <имя_скрипта> param1 param2 «еще один текстовый параметр«
В самом скрипте параметры могут быть получены так:
param ($var1, $var2, $var3)
В интегрированной среде PowerShell ISE скрипт с параметрами можно запустить аналогично, используя область команд.
Вывести уведомление пользователю Windows из скрипта PowerShell
С помощью класса Windows Forms можно вывести более красивые всплывающие сообщения (ballons). Следующий скрипт выведет всплывающее сообщение рядом с панелью уведомлений Windows, которое автоматически исчезнет через 10 секунд:

Для создания красочных всплывающих сообщений в Windows можно использовать отдельный PowerShell модуль BurntToast.
Установите модуля из PowerShell Gallery:
Install-Module -Name BurntToast
Теперь, например, в ранее рассматриваемый скрипт автоматического отключения от Wi-FI сети при подключении к Ethernet можно добавить уведомление с картинкой:
New-BurntToastNotification -Text "Отключение от Wi-Fi сети", "Вы были отключены от Wi-Fi сети, т.к. Вше устройство было подключено к скоростному Ethernet подключению." -AppLogo C:\PS\changenetwork.png

Как разрешить выполнение неподписанного скрипта PowerShell?
- В оболочке PowerShell перед запуском скрипта выполните следующую команду для разрешения выполнения неподписанных скриптов в текущем сеансе оболочки:
Set-ExecutionPolicy RemoteSigned -Scope Process
- При запуске из стандартного командного интерфейса используйте параметр -executionpolicy, например:
PowerShell -executionpolicy RemoteSigned -file <имя_скрипта>
Оба способа устанавливают политику только для текущего сеанса, при этом политика безопасности выполнения скриптов PowerShell, установленная в реестре, остается неизменной. Если вы хотите изменить политику безопасности выполнения скриптов «навсегда», используйте следующий способ:
- Разрешить выполнение навсегда: запустите оболочку PowerShell от имени «Администратора» и выполните команду:
Однако рекомендуется избегать этого способа, чтобы не подвергать ваш компьютер возможным угрозам, поскольку это разрешает выполнение всех скриптов всегда.
Примечание: Если скрипт был загружен из интернета, чтобы избежать запроса на подтверждение выполнения, используйте параметр Bypass вместо RemoteSigned — это полное отключение любых запросов и предупреждений.
Командные скрипты Windows
Это общий термин, который включает в себя различные типы скриптов и командных файлов, используемых в операционной системе Windows для автоматизации задач. Включают в себя как скрипты на языке командной строки (например, скрипты CMD), так и на более современных языках, таких как PowerShell. Например, Bat-скрипты (*.bat), PowerShell-скрипты (*.ps1), а также другие сценарии, созданные для автоматизации определенных задач.
Как запустить скрипт PowerShell в фоновом режиме?
Для этого используйте параметр -WindowStyle, который может принимать значения: Normal, Minimized, Maximized и Hidden. Чтобы запустить неподписанный скрипт в фоновом режиме, выполните команду:
PowerShell -executionpolicy RemoteSigned -WindowStyle Hidden -file <имя_скрипта>
Также при желании вы можете добавить -NonInteractive, чтобы скрипт не задавал никаких вопросов. Таким образом, скрипт выполнится незаметно для пользователя. Однако будьте внимательны, используя этот способ.
Как запустить скрипт PowerShell с помощью ярлыка?
Это можно сделать двумя способами:
- Создать файл bat/cmd, в котором прописать команду для запуска скрипта (с параметрами, как описано выше).
- Создать ярлык на PowerShell, который находится в папке c:\Windows\System32\WindowsPowerShell\v<версия>\. В свойствах ярлыка в поле «Объект» добавьте необходимые параметры.
Таким образом, например, чтобы запустить скрипт PowerShell при входе пользователя, просто создайте ярлык, как описано во втором пункте, и поместите его в автозагрузку. Также создание ярлыка с использованием одного из вышеописанных методов позволяет легко запускать скрипт от имени администратора или от имени любого другого пользователя, как обычную программу.
Скриптовый язык PowerShell — мощный инструмент для решения различных задач. Однако следует использовать его с осторожностью, поскольку он может быть использован не только для полезных, но и для вредоносных целей. Будьте внимательны при работе с ним.
Как сделать и запустить скрипт PowerShell
Создать скрипт PowerShell довольно просто. Вот шаги, которые вы можете выполнить, чтобы создать свой первый скрипт:
1. Откройте редактор PowerShell ISE:
PowerShell ISE (Integrated Scripting Environment) предоставляет удобную среду для написания и отладки скриптов. Вы можете его найти в меню «Пуск» (Start) под разделом «Стандартные» (Standard) или выполнить команду `PowerShell_ise` в командной строке.
2. Напишите свой скрипт:
В окне редактора PowerShell ISE напишите свой скрипт. Ниже приведен пример простого скрипта, который выводит «Hello, World!» в консоль:
Write-Host «Hello, World!»
3. Сохраните скрипт:
- Нажмите `Ctrl + S` или выберите «Файл» (File) -> «Сохранить» (Save).
- Укажите имя файла и добавьте расширение `.ps1` (например, `MyScript.ps1`).
4. Запустите скрипт:
- Выберите весь текст скрипта.
- Нажмите `F5` или выберите «Запустить сценарий» (Run Script) в PowerShell ISE.
Примеры более сложных скриптов:
#Скрипт, создающий новую папку:
$folderPath = «C:\Path\To\NewFolder»
New-Item -ItemType Directory -Path $folderPath
#Скрипт, удаляющий все файлы старше 7 дней в папке:
$folderPath = «C:\Path\To\Folder»
$limitDate = (Get-Date).AddDays(-7)
#Скрипт, проверяющий статус службы:
Write-Host «The status of service $serviceName is: $($serviceStatus.Status)»
Ваши скрипты могут включать более сложные команды, использовать условия, циклы и вызывать функции. Как только вы освоите основы, вы сможете создавать более мощные и гибкие скрипты PowerShell.
Скрипты для Windows — не просто строки кода, а волшебные ключи, открывающие дверь в мир автоматизации. В руках умелого пользователя они становятся инструментом, способным не только сэкономить время, но и превратить рутинные задачи в захватывающее путешествие по потокам байтов и командам.
Как запустить скрипт в PowerShell?
Существует несколько способов запуска скрипта, вот основные из них:
- Запустить оболочку PowerShell и выполнить в ней скрипт, указав путь к файлу и его имя (например, C:\Scripts\test.ps1) или перейдя в каталог скрипта командой cd C:\Scripts и выполнить его с помощью команды .\test.ps1.
- Оболочку можно найти и запустить разными способами. Один из них — через меню «Пуск». Для Windows 7 пройдите по следующему пути: «Все программы» — «Стандартные» — «Windows PowerShell» и запустите оболочку «Windows PowerShell». Для Windows 10 найдите группу по букве «W» и в ней выберите «Windows PowerShell».
- Запустить «Интегрированную среду сценариев Windows PowerShell ISE», которая представляет собой среду разработки, позволяющую редактировать и отлаживать скрипты PowerShell. Откройте программу, выберите «Открыть» или в меню Файл выберите «Открыть» и укажите нужный скрипт, затем нажмите F5 или кнопку «Выполнить скрипт». Поиск Windows PowerShell ISE можно осуществить так же, как и оболочки PowerShell, через меню «Пуск».
- Запустить стандартный командный интерфейс и ввести следующую команду:
PowerShell -file <имя_скрипта> (например: PowerShell -file myscript.ps1)
Если вы ранее не запускали скрипты PowerShell, возможно, вы получите сообщение о том, что файл <имя_скрипта> не может быть загружен, так как выполнение скриптов запрещено для данной системы. В этом случае введите «get-help about_signing» для получения дополнительной информации. Это связано с безопасностью и предотвращением случайного выполнения вредоносного кода, поэтому все скрипты должны быть подписаны цифровой подписью.
Выполняемые скрипты Windows
Это скрипты, которые могут быть выполнены в среде операционной системы Windows и обычно предназначены для автоматизации различных задач. Включают в себя bat-скрипты (командные файлы), PowerShell-скрипты, а также другие типы скриптов, которые можно выполнять в Windows. Общее отличие между bat-скриптами и PowerShell-скриптами заключается в языке программирования, используемом для написания команд и инструкций. Bat-скрипты используют язык пакетных команд, который является устаревшим и имеет ограниченные возможности по сравнению с PowerShell, который представляет более современный и мощный язык с разнообразными функциональными возможностями для автоматизации задач в Windows.
Вывести всплывающее сообщение на экран с помощью PowerShell
Для вывода простых модального диалогового окна в Windows можно воспользоваться Wscript классами подсистемы сценариев Windows. Следующий PowerShell код выведет обычное текстовое окно с вашим текстом и кнопкой OK.
$wshell = New-Object -ComObject Wscript.Shell
$Output = $wshell.Popup("Скрипт формирования отчета выполнен")

Вы можете настроить вид модального окна такого сообщения и добавить кнопки действия для пользователей. Например, чтобы вывести всплывающее окно с кнопками Да и Нет, выполните:

$Output = $wshell.Popup("Скрипт формирования отчета завершен! Хотите вывести его на экран?",0,"Отчет готов",4+32)
Если пользователь нажмет Да, команда вернет значение
6
, а если Нет –
7
.
В зависимости от выбора пользователя вы можете выполнить какое-то действие, или завершить скрипт.
switch ($Output) { 7 {$wshell.Popup('Нажата Нет')} 6 {$wshell.Popup('Нажата Да')}
default {$wshell.Popup('Неверный ввод')} } Общий синтаксис и параметры метода Popup:
- <Text> — текст сообщения.
- <SecondsToWait> — необязательный, число. Количество секунд, по истечении которого окно будет автоматически закрыто.
- <Title> — текст заголовка окна сообщения (необязательный параметр).
- <Type> — комбинация флагов, определяет тип кнопок и вид значка (числовое значение, не обязательный параметр). Возможные значения флагов:
- 0 — кнопка ОК.
- 1 — кнопки ОК и Отмена.
- 2 — кнопки Стоп, Повтор, Пропустить.
- 3 — кнопки Да, Нет, Отмена.
- 4 — кнопки Да и Нет.
- 5 — кнопки Повтор и Отмена.
- 16 — значок Stop.
- 32 — значок Question.
- 48 — значок Exclamation.
- 64 — значок Information.
Команда PowerShell возвращает целое значение, с помощью которого можно узнать, какая кнопка была нажата пользователем. Возможные значения:
- -1 — таймаут.
- 1 — кнопка ОК.
- 2 — кнопка Отмена.
- 3 — кнопка Стоп.
- 4 — кнопка Повтор.
- 5 — кнопка Пропустить.
- 6 — кнопка Да.
- 7 — кнопка Нет.
Если нужно показать пользователю окно ввода и запросить данные, воспользуйтесь классом Windows Forms.
Чтобы обработать введенные пользователе данные:
if ([string]::IsNullOrWhiteSpace($input)) { Write-Host "Данные не указаны"
} else { Write-Host "Вы ввели $input"
}
Если нужно вывести всплывающее окно поверх всех окон, используйте команду:
Про безопасность
Продолжая тему безопасности давайте рассмотрим еще несколько скриптов, позволяющих выявлять в системе не слишком желательные процессы. В частности, процесс Psexec.
PsExec позволяет выполнять процессы в других системах с полным взаимодействием для консольных приложений, не устанавливая клиентское программное обеспечение вручную. То есть, мы можем подключаться к удаленным системам, и выполнять на них необходимые команды.
Psexec в общем случае не является хакерской утилитой (хотя в Metasploit есть эксплоиты, реализующие функционал данной утилиты), и с ее помощью администраторы могут выполнять массу полезных задач в клиентских системах. Поэтому просто запретить ее использование мы не можем, но хотелось бы мониторить появление соответствующего процесса в системе.
Для этого можно воспользоваться следующим скриптом.
$PSExecmon = get-process | Where-Object { $_.description -like "*psexec*" }
if (!$PSExecmon) {
$PSExecHealth = "Healthy - no PSExec service found."
} else {
$PSExecHealth = "Unhealthy - PSExec service found"
}
write-host $PSExecHealthЗдесь мы специально ищем по маске, на случай переименования с помощью команды psexec -r. Но злоумышленники могут пойти дальше и в принципе изменить персональные идентификаторы процесса. В таком случае, мы можем попробовать поискать psexec по сертификату Майкрософт, которым он подписан.
$Procs = Get-Process | Where-Object { $_.Path -ne $null }
$PSExecmon = foreach ($Proc in $procs) {
$Sig = Get-AuthenticodeSignature $proc.path
if ($Sig.SignerCertificate.Thumbprint -eq "3BDA323E552DB1FDE5F4FBEE75D6D5B2B187EEDC") { $proc }
}
if (!$PSExecmon) {
$PSExecHealth = "Healthy - no PSExec service found."
} else {
$PSExecHealth = "Unhealthy - PSExec service found"
}
write-host $PSExecHealthЗдесь правда есть риск столкнуться с ложными срабатываниями, так как данную подпись используют также другие решения Майкрософт, например .NET.
Продолжая эту тему, также хотелось бы рассмотреть еще один скрипт для мониторинга, который отслеживает любое приложение, запущенное из под SYSTEM и у которого нет идентификатора сеанса 0. Идентификатор сеанса 0 обычно используется только для служб и процессов, которые должны запускаться как системные. Если у вас есть приложение, запущенное под любым другим идентификатором сеанса, это означает, что оно использовало интерактивный вход в систему.
Также возможна ситуация, когда некоторые приложения запускаются в режиме интерактивного сеанса, и тогда нужно будет исключить эти процессы.
Для списка исключений мы используем переменную $ExcludedList. Далее получаем общий список процессов, извлекаем из него запущенные с правами SYSTEM и с ненулевым идентификатором.
$ExcludedList = "RtkAuduService64","Winlogon","SomeRMMApp"
$StrangeProcesses = get-process -IncludeUserName | Where-Object {$_.username -like "\*SYSTEM" -and $_.SessionId -ne 0 -and $\_.ProcessName -notin $ExcludedList}
if($StrangeProcesses){
Write-Host "Processes found running as system inside an interactive session. Please investigate"
$StrangeProcesses
} else {
write-host "Healthy. No processes found."
}Таким образом, мы можем обнаруживать попытки поднятия привилегий на ранних стадиях..
Заключение
В этой статье мы рассмотрели несколько полезных скриптов на Powershell, которые могут использоваться для решения различных задач мониторинга. Стоит отметить, что это лишь малая часть тех задач мониторинга, которые можно решить с помощью Powershell.
Хочу пригласить вас на бесплатный вебинар про инвентаризацию Active Directory с помощью Powershell, а также на вебинар про групповые политики Windows.



