Основы команд PowerShell — операции, которые стоит выучить первыми, и как использовать их безопасно
· Обновлено: · Го Комура · PowerShell, Windows, Командная строка, Автоматизация, Использование существующих активов
История изменений (4 обновлений, последнее 30 Aug 2026)
Журнал изменений этой статьи. Там, где версия до правки была заархивирована, она остаётся доступной для чтения по постоянной ссылке с DOI.
- Русский текст переписан как полноценный технический перевод, а не калька с японского. Утверждения статьи не менялись.
- В начало статьи добавлен раздел «Карта знаний этой статьи». Это сводка понятий, которые разбираются в тексте, и связей между ними: краткое описание, схема и ссылка на страницу сведений. Утверждения в основном тексте не менялись.
- Текст обновлён по итогам внешнего рецензирования (1283 замечания). Содержание отдельных правок см. в записях ниже.
- В главу 1 добавлены путеводитель по чтению в зависимости от задачи и таблица восьми команд, которые стоит выучить первыми. Дополнены таблица различий 5.1 и 7.x, столбцы по умолчанию у Get-Process, Get-ChildItem и Get-WinEvent и как их читать, разграничение с подборкой практических команд; в справочные ссылки добавлены три пункта.
- Первая публикация
Цитирование статьи(DOI (зарегистрированный архив): 10.5281/zenodo.21619864)
Приведённые ниже DOI относятся к ранее зарегистрированным архивным версиям, которые могут отличаться от текущего текста. Для ссылки на текущий текст используйте URL этой страницы.
Го Комура (2026). Основы команд PowerShell — операции, которые стоит выучить первыми, и как использовать их безопасно. KomuraSoft LLC. https://comcomponent.com/ru/blog/2026/05/29/powershell-command-basics/
- DOI (зарегистрированный архив)
- 10.5281/zenodo.21619864
- DOI (последняя зарегистрированная версия)
- 10.5281/zenodo.21619865
1. Что стоит понять в первую очередь
PowerShell — командная среда, которой пользуются, чтобы проверить настройки Windows, навести порядок в файлах, разобрать логи, обработать CSV, управлять службами и автоматизировать однотипные задачи.
Сложные скрипты с первого дня писать не нужно. Если освоить только такую последовательность, этого уже хватает для повседневной работы.
искать → смотреть → отфильтровать → отсортировать → вывести → при необходимости изменить
Основа PowerShell — не «зазубрить длинные команды». Важны три вещи:
- Умение искать команды через
Get-CommandиGet-Help - Умение передавать результат следующей команде через конвейер
| - Проверка последствий через
-WhatIfи-Confirmперед удалением, остановкой или изменением
PowerShell позволяет вести «исследование» и «изменение» на одном и том же экране. Это удобно, но удаление или остановка выполняются так же мгновенно, поэтому важна привычка начинать с проверок, доступных только для чтения.
Код, который встречается в этой статье, опубликован на GitHub в виде полного набора примеров: коллекция скриптов по темам, соответствующим главам статьи (её можно безопасно прогонять в рабочей области, которую скрипты создают во временной папке), а также тесты Pester.
powershell-command-basics - komurasoft-blog-samples (GitHub)
Как читать эту статью
В статье 26 глав. Читать её подряд с самого начала не обязательно. В зависимости от задачи удобнее начинать с таких глав:
| Задача | Какие главы читать |
|---|---|
| Только начинаете работать с PowerShell | главы 1–8 (подход, как искать, конвейер, операции с файлами) и глава 24 (порядок изучения) |
| Нужно разобрать логи или настройки | глава 9 (текст), глава 12 (процессы и службы), глава 13 (журнал событий), глава 21 (пример расследования) |
| Нужно обработать CSV или JSON | главы 10, 11, 15 |
| Нужно оформить обработку как скрипт | главы 14, 16, 17, 18 |
| Нужно безопасно удалять или перемещать | главы 19, 22, 25 |
| Нужна только шпаргалка по командам | глава 20 (список базовых команд), глава 23 (типичные сбои) |
Сам порядок изучения собран в главе 24 «В каком порядке учить команды». Когда впервые садитесь за консоль, держите под рукой только первый этап из главы 24 (Get-Command, Get-Help, Get-Member, Get-Location, Set-Location, Get-ChildItem, Get-Content, Select-String) и идите по тексту. Этих восьми команд достаточно, чтобы остальное искать по мере появления задачи.
Чем эта статья отличается от «подборки практических команд»
По PowerShell есть ещё одна статья. Роли у них разные, поэтому ими пользуются так:
| Статья | О чём | Когда читать |
|---|---|---|
| Эта статья (основы) | Система операций: как искать команды, как устроен конвейер, в каком порядке безопасно выполнять изменяющие команды | Читать первой |
| Практические команды PowerShell | Готовые куски под задачу: подсчёт числа и суммы (Measure-Object), группировка (Group-Object), сравнение (Compare-Object), запись рабочего журнала (Start-Transcript) и т. п. |
Когда в работе появляется конкретное «хочу сделать вот это» |
CSV, процессы, службы, журнал событий и оговорки про Format-* встречаются в обеих. Здесь разбираем, почему пишут именно так; в подборке практических команд — какой кусок взять в этой ситуации.
На схеме сплошная линия обозначает отношение, которое выполняется всегда, а пунктирная — условное отношение (условия указаны в пояснении к каждому отношению на странице сведений). Полный список отношений (всего 20, с доказательствами и степенью уверенности) и определения основных понятий собраны на странице сведений карты знаний (на японском). Данные: JSON-LD / Turtle
2. Чем PowerShell отличается от командной строки
PowerShell внешне похож на привычную командную строку (cmd.exe), но внутренняя модель другая.
| Аспект | Командная строка | PowerShell |
|---|---|---|
| Основной вывод | строки текста | объекты |
| Имена команд | dir, copy и т. д. |
Get-ChildItem, Copy-Item и т. д. |
| Обработка результата | в основном обработка строк | фильтрация и сортировка по свойствам |
| Автоматизация | пакетные файлы | скрипты .ps1 |
| Сильная сторона | совместимость со старыми командными наработками | администрирование Windows, CSV, JSON, API, однотипные задачи |
Например, список файлов в cmd.exe чаще всего смотрят как текст, который вывел dir. В PowerShell файл — это объект со свойствами Name, Length, LastWriteTime и другими.
Get-ChildItem
Когда это различие понятно, операции вроде «показать только файлы, изменённые за последние 7 дней, от новых к старым» пишутся естественно.
Get-ChildItem -File |
Where-Object { $_.LastWriteTime -gt (Get-Date).AddDays(-7) } |
Sort-Object LastWriteTime -Descending |
Select-Object Name, Length, LastWriteTime
3. Windows PowerShell 5.1 и PowerShell 7.x
В Windows давно есть Windows PowerShell 5.1, а рядом — новая линейка PowerShell 7.x.
На практике удобно думать так.
| Вариант | Исполняемый файл | Основное назначение |
|---|---|---|
| Windows PowerShell 5.1 | powershell.exe |
старые модули только для Windows, уже существующие скрипты, сопровождение внутренних наработок |
| PowerShell 7.x | pwsh.exe |
новые скрипты, кроссплатформенность, постоянные улучшения |
Если изучаете с нуля, ориентироваться на PowerShell 7.x можно. Но старые внутренние управляющие скрипты и модули, специфичные для Windows, иногда рассчитаны именно на Windows PowerShell 5.1.
Поэтому на практике сначала проверяют версию.
$PSVersionTable
Для скрипта, который должен запускаться только на определённой версии и новее, условие в начале файла снижает число аварий.
#Requires -Version 7.0
На какой версии работают примеры из этой статьи
Дальнейшие примеры, если не оговорено иное, написаны так, чтобы без правок работать и в Windows PowerShell 5.1, и в PowerShell 7.x. Но даже у одной и той же команды результат в следующих местах отличается — проверьте это, прежде чем копировать.
| Где расходятся | Windows PowerShell 5.1 | PowerShell 7.x |
|---|---|---|
Столбцы Get-Process по умолчанию |
Handles, NPM(K), PM(K), WS(K), CPU(s), Id, SI, ProcessName |
NPM(K), PM(M), WS(M), CPU(s), Id, SI, ProcessName (память в МБ) |
Что означает -Encoding UTF8 |
UTF-8 (с BOM) | UTF-8 (без BOM). Чтобы добавить BOM, указывают utf8BOM |
Если -Encoding не указан |
зависит от команды (Out-File — UTF-16LE, Set-Content — ANSI, Export-Csv — ASCII) |
везде utf8NoBOM |
В примерах этой статьи у команд записи явно указан -Encoding UTF8, чтобы не получить неожиданную кодировку. Сама логика BOM и переводов строк разобрана в статье Кодировки текста и переводы строк в Windows.
4. Имена командлетов в форме «глагол-существительное»
Стандартные команды PowerShell в основном имеют форму Глагол-Существительное.
Get-Process
Get-Service
Get-ChildItem
Copy-Item
Remove-Item
Export-Csv
Когда эта форма усвоена, даже незнакомые команды проще искать.
| Глагол | Значение | Пример |
|---|---|---|
Get |
получить | Get-Process |
Set |
задать | Set-Location |
New |
создать | New-Item |
Copy |
скопировать | Copy-Item |
Move |
переместить | Move-Item |
Remove |
удалить | Remove-Item |
Start |
запустить | Start-Service |
Stop |
остановить | Stop-Process |
Import |
загрузить | Import-Csv |
Export |
выгрузить | Export-Csv |
Короткие имена вроде dir, ls, cat, cd тоже работают, но большинство из них — псевдонимы (aliases).
Get-Command dir
Если код остаётся в виде скрипта, безопаснее писать полные имена, а не псевдонимы.
# читается легко, но в скриптах лучше избегать
ls *.log
# намерение однозначно
Get-ChildItem -Filter *.log
5. Три команды для исследования, которые стоит выучить первыми
Команд в PowerShell очень много, поэтому на практике полезнее выучить «как искать», а не пытаться всё запомнить.
1. Get-Command — найти доступные команды
Get-Command ищет установленные команды, функции, псевдонимы и приложения.
# Найти команды с существительным Process
Get-Command -Noun Process
# Найти команды, связанные со службами
Get-Command *Service*
# Найти команды, связанные с CSV
Get-Command *Csv*
Если имя команды помнится неточно, используйте подстановочные знаки.
Get-Command *Item*
Get-Command *Content*
Get-Command *Json*
2. Get-Help — посмотреть, как пользоваться командой
Get-Help показывает описание команды, параметры и примеры.
Get-Help Get-ChildItem
Get-Help Get-ChildItem -Examples
Get-Help Get-ChildItem -Full
Get-Help Get-ChildItem -Online
Сначала удобнее всего -Examples.
Get-Help Where-Object -Examples
Если справка устарела или её не хватает, обновите её из PowerShell, запущенного с правами администратора.
Update-Help
В зависимости от окружения для этого нужны доступ в интернет и права. На корпоративных ПК команда может не сработать из-за прокси или политик управления.
3. Get-Member — посмотреть содержимое объекта
Вывод PowerShell в большинстве случаев — не «строка текста», а «объект». Через Get-Member видно, какие свойства и методы есть у этого объекта.
Get-Process | Get-Member
Get-Service | Get-Member
Get-ChildItem | Get-Member
Например, у службы есть свойства Status, Name и другие.
Get-Service | Select-Object Name, Status
У файла есть Name, Length, LastWriteTime и другие.
Get-ChildItem -File | Select-Object Name, Length, LastWriteTime
Когда непонятно, «по чему фильтровать», сначала посмотрите имена свойств через
Get-Member.
6. Основы конвейера
| в PowerShell передаёт результат левой команды правой.
Get-Process | Sort-Object CPU -Descending | Select-Object -First 10
В этом примере обработка идёт слева направо в таком порядке.
получить список процессов
→ отсортировать по убыванию использования CPU
→ показать только первые 10
Как выглядит вывод
Результат Get-Process по умолчанию выводится таблицей со следующими столбцами. Значения на каждой машине свои, смотреть нужно «порядок столбцов».
NPM(K) PM(M) WS(M) CPU(s) Id SI ProcessName
------ ----- ----- ------ -- -- -----------
| Столбец | Смысл |
|---|---|
NPM(K) |
объём памяти в невыгружаемом пуле (КБ) |
PM(M) |
объём выгружаемой памяти (МБ) |
WS(M) |
размер рабочего набора (Working Set) — недавно использованных страниц памяти (МБ) |
CPU(s) |
процессорное время на всех процессорах (секунды) |
Id |
идентификатор процесса |
SI |
идентификатор сеанса |
ProcessName |
имя процесса |
Это отображение по умолчанию в PowerShell 7.x. В Windows PowerShell 5.1 в начале появляется Handles (число открытых handle), а столбцы памяти — PM(K) и WS(K) в КБ. Имена столбцов на экране могут отличаться, но имена свойств, которые передают в Sort-Object и Where-Object (CPU, WorkingSet, Id, Name и т. д.), общие. Имя столбца для отображения и имя свойства — разные вещи. Если условие фильтрации не срабатывает, проверьте настоящее имя свойства через Get-Process | Get-Member.
Часто используют такие сочетания.
| Команда | Роль | Пример |
|---|---|---|
Where-Object |
отфильтровать по условию | получить только остановленные службы |
Sort-Object |
отсортировать | отсортировать по времени изменения, от новых к старым |
Select-Object |
выбрать столбцы или число записей | показать только имя и размер |
ForEach-Object |
обработать каждый элемент | обработать каждый файл по отдельности |
Export-Csv |
вывести в CSV | сохранить результаты исследования |
Where-Object — отфильтровать по условию
# Показать только остановленные службы
Get-Service | Where-Object { $_.Status -eq "Stopped" }
# Показать только файлы размером более 100 МБ
Get-ChildItem -File |
Where-Object { $_.Length -gt 100MB }
# Показать только файлы, в имени которых есть backup
Get-ChildItem -File |
Where-Object { $_.Name -like "*backup*" }
$_ обозначает текущий объект, который сейчас идёт по конвейеру.
Where-Object { $_.Length -gt 100MB }
Это проверка: «больше ли Length рассматриваемого сейчас файла, чем 100 МБ».
Начиная с PowerShell 3.0 доступен и упрощённый синтаксис.
Get-Service | Where-Object Status -EQ "Stopped"
Пока вы новичок, синтаксис со scriptblock проще для понимания смысла.
Get-Service | Where-Object { $_.Status -eq "Stopped" }
Sort-Object — отсортировать
# По убыванию использования памяти
Get-Process |
Sort-Object WorkingSet -Descending |
Select-Object -First 10 Name, Id, WorkingSet
# По убыванию времени изменения (сначала новые)
Get-ChildItem -File |
Sort-Object LastWriteTime -Descending |
Select-Object -First 20 Name, LastWriteTime
Select-Object — оставить только нужные столбцы
Get-Process |
Select-Object Name, Id, CPU, WorkingSet
Ещё им ограничивают число записей.
Get-Process | Select-Object -First 5
Get-Process | Select-Object -Last 5
Перед выводом в CSV удобно заранее оставить только нужные столбцы через Select-Object.
Get-Service |
Select-Object Name, DisplayName, Status, StartType |
Export-Csv .\services.csv -NoTypeInformation -Encoding UTF8
7. Командлеты Format-* ставьте в самый конец
В PowerShell есть команды, которые оформляют вывод для экрана.
Format-Table
Format-List
Format-Wide
Они нужны «для отображения на экране». Если поставить их перед выводом в CSV или перед передачей дальше по конвейеру, вместо исходных свойств получится объект для отображения.
# Не делать так: в CSV попадает информация для отображения
Get-Process |
Format-Table Name, CPU |
Export-Csv .\process.csv -NoTypeInformation
# Правильно: сначала выбрать свойства, затем вывести в CSV
Get-Process |
Select-Object Name, CPU |
Export-Csv .\process.csv -NoTypeInformation -Encoding UTF8
Если запомнить
Format-*как «команды, которыми в самом конце показывают результат на экране», аварий станет меньше.
8. Основы работы с файлами и папками
Чаще всего в PowerShell работают с файлами и папками.
| Что нужно сделать | Команда |
|---|---|
| Посмотреть текущее расположение | Get-Location |
| Перейти в другое расположение | Set-Location |
| Посмотреть список | Get-ChildItem |
| Создать файл или папку | New-Item |
| Скопировать | Copy-Item |
| Переместить | Move-Item |
| Переименовать | Rename-Item |
| Удалить | Remove-Item |
| Проверить, существует ли объект | Test-Path |
Проверить текущее расположение
Get-Location
Переход.
Set-Location C:\Work
Если в пути есть пробелы, заключите его в кавычки.
Set-Location "C:\Work Files\Reports"
Посмотреть список файлов
Get-ChildItem
Get-ChildItem -File
Get-ChildItem -Directory
Get-ChildItem -Recurse
После запуска под заголовком целевой папки появляется таблица со следующими столбцами.
Directory: C:\Work
Mode LastWriteTime Length Name
---- ------------- ------ ----
Mode — это буквы атрибутов: d — каталог, a — архивный, r — только чтение, h — скрытый, s — системный, l — ссылка. В строках каталогов Length (размер) пустой. Имена LastWriteTime и Length, которые здесь видны, — те же имена свойств, которые можно передавать в Where-Object и Sort-Object.
Для фильтрации по расширению удобен -Filter.
Get-ChildItem -Filter *.log
Чтобы искать и во вложенных папках, используйте -Recurse.
Get-ChildItem C:\Logs -Filter *.log -Recurse
В местах с большим количеством файлов не запускайте -Recurse сразу — сначала ограничьте целевую папку.
Создание
# Создание папки
New-Item -ItemType Directory -Path .\archive
# Создание пустого файла
New-Item -ItemType File -Path .\memo.txt
Если объект может уже существовать, сначала проверьте это.
if (-not (Test-Path .\archive)) {
New-Item -ItemType Directory -Path .\archive
}
Копирование
Copy-Item .\report.xlsx .\backup\report.xlsx
Чтобы скопировать папку целиком, используйте -Recurse.
Copy-Item .\data .\backup\data -Recurse
Если возможна перезапись, заранее проверьте последствия.
Copy-Item .\data .\backup\data -Recurse -WhatIf
Перемещение
Move-Item .\old.log .\archive\old.log
Когда по условию перемещаете несколько файлов, сначала добавьте -WhatIf.
Get-ChildItem .\logs -Filter *.log |
Where-Object { $_.LastWriteTime -lt (Get-Date).AddDays(-30) } |
Move-Item -Destination .\archive -WhatIf
Если всё в порядке, уберите -WhatIf.
Get-ChildItem .\logs -Filter *.log |
Where-Object { $_.LastWriteTime -lt (Get-Date).AddDays(-30) } |
Move-Item -Destination .\archive
Удаление
К удалению относитесь особенно осторожно.
Remove-Item .\old.log -WhatIf
Выполняйте только после того, как убедились, что объект выбран правильно.
Remove-Item .\old.log
Сочетание подстановочных знаков и -Recurse — мощный инструмент. Не запускайте его сразу в рабочей папке: сначала проверьте список.
# Сначала проверить объекты
Get-ChildItem C:\Logs -Filter *.tmp -Recurse |
Select-Object FullName, Length, LastWriteTime
# Затем проверить план удаления
Get-ChildItem C:\Logs -Filter *.tmp -Recurse |
Remove-Item -WhatIf
# И наконец выполнить
Get-ChildItem C:\Logs -Filter *.tmp -Recurse |
Remove-Item
9. Чтение, поиск и запись текстовых файлов
При разборе логов постоянно работают с текстовыми файлами.
Чтение файла
Get-Content .\app.log
Чтобы посмотреть только конец файла, используйте -Tail.
Get-Content .\app.log -Tail 50
Чтобы наблюдать за дописываемым логом, используйте -Wait.
Get-Content .\app.log -Tail 20 -Wait
Поиск строк
Select-String -Path .\app.log -Pattern "ERROR"
Можно указать несколько файлов.
Select-String -Path .\logs\*.log -Pattern "ERROR", "WARN"
Из результатов поиска можно извлечь имя файла, номер строки и содержимое и сохранить их в CSV.
Select-String -Path .\logs\*.log -Pattern "ERROR" |
Select-Object Path, LineNumber, Line |
Export-Csv .\error-lines.csv -NoTypeInformation -Encoding UTF8
Запись в файл
"hello" | Set-Content .\memo.txt -Encoding UTF8
"next line" | Add-Content .\memo.txt -Encoding UTF8
Когда сохраняют результат команды, Export-Csv или ConvertTo-Json иногда удобнее для дальнейшей работы, чем Out-File.
Get-Process |
Select-Object Name, Id, CPU |
Export-Csv .\process.csv -NoTypeInformation -Encoding UTF8
10. Основы работы с CSV
В автоматизации бизнес-процессов CSV встречается очень часто. В PowerShell CSV обрабатывается не как строки текста, а как «объекты со столбцами».
Чтение CSV
Например, предположим, что есть такой файл users.csv.
Name,Department,Enabled
Suzuki,Sales,true
Tanaka,Accounting,false
Sato,Sales,true
Загрузка.
$users = Import-Csv .\users.csv
$users
Имена столбцов становятся свойствами.
$users | Select-Object Name, Department
Фильтрация по условию
$users |
Where-Object { $_.Department -eq "Sales" }
Значения из CSV часто загружаются как строки, поэтому будьте внимательны при работе с true / false или числами.
$users |
Where-Object { $_.Enabled -eq "true" }
Вывод в CSV
$users |
Where-Object { $_.Department -eq "Sales" } |
Export-Csv .\sales-users.csv -NoTypeInformation -Encoding UTF8
Железное правило — никогда не ставить Format-Table перед Export-Csv.
# Не делать так
$users | Format-Table | Export-Csv .\out.csv -NoTypeInformation
# Правильно
$users | Select-Object Name, Department, Enabled | Export-Csv .\out.csv -NoTypeInformation -Encoding UTF8
11. Основы работы с JSON
В конфигурационных файлах и веб-API также часто встречается JSON.
$data = Get-Content .\settings.json -Raw | ConvertFrom-Json
$data
Преобразование объекта в JSON.
[pscustomobject]@{
Name = "BatchJob"
Enabled = $true
Retry = 3
} | ConvertTo-Json
При глубокой вложенности укажите -Depth.
$config | ConvertTo-Json -Depth 10 | Set-Content .\settings.json -Encoding UTF8
12. Основы работы с процессами и службами
Просмотр процессов
Get-Process
Проверка процессов с наибольшим использованием памяти.
Get-Process |
Sort-Object WorkingSet -Descending |
Select-Object -First 10 Name, Id, WorkingSet
Фильтрация по имени.
Get-Process -Name notepad
Остановку выполняйте осторожно.
Stop-Process -Name notepad -WhatIf
Если всё в порядке, выполните.
Stop-Process -Name notepad
Просмотр служб
Get-Service
Если нужно посмотреть только остановленные службы.
Get-Service |
Where-Object { $_.Status -eq "Stopped" }
Фильтрация по имени.
Get-Service -Name "Spooler"
При перезапуске тоже сначала проверьте объект.
Get-Service -Name "Spooler"
Restart-Service -Name "Spooler" -WhatIf
Операции со службами легко влияют на бизнес-процессы, поэтому в рабочей среде сначала проверьте регламент, окно обслуживания и способ восстановления.
13. Основы работы с журналом событий
При исследовании Windows журнал событий незаменим.
Проверка недавних ошибок.
Get-WinEvent -LogName System -MaxEvents 100 |
Where-Object { $_.LevelDisplayName -eq "Error" } |
Select-Object TimeCreated, ProviderName, Id, Message
Как выглядит вывод
Результат Get-WinEvent по умолчанию группируется заголовками по источнику журнала (ProviderName); под каждым заголовком идёт таблица со следующими столбцами.
ProviderName: PowerShell
TimeCreated Id LevelDisplayName Message
----------- -- ---------------- -------
Если, как в примере выше, столбцы выбирают через Select-Object, заголовок источника не появляется: остаётся таблица только из выбранных столбцов. Message длинный, поэтому на экране он обрезается. Чтобы прочитать одну запись целиком, сузьте выборку до одной записи и покажите её через Format-List.
Get-WinEvent -LogName System -MaxEvents 1 | Format-List *
В LevelDisplayName бывают значения Critical, Error, Warning, Information, Verbose. На больших журналах передавать условие в -FilterHashtable быстрее, чем фильтровать через Where-Object (Level = 3 — предупреждение, Level = 4 — сведения).
Просмотр последних 50 записей журнала приложений.
Get-WinEvent -LogName Application -MaxEvents 50 |
Select-Object TimeCreated, ProviderName, Id, LevelDisplayName, Message
Фильтрация по периоду.
$start = (Get-Date).AddHours(-24)
Get-WinEvent -FilterHashtable @{
LogName = "System"
StartTime = $start
} |
Select-Object TimeCreated, ProviderName, Id, LevelDisplayName, Message
Если сохранить результаты исследования в CSV, ими будет проще делиться позже.
Get-WinEvent -LogName System -MaxEvents 500 |
Where-Object { $_.LevelDisplayName -in @("Error", "Warning") } |
Select-Object TimeCreated, ProviderName, Id, LevelDisplayName, Message |
Export-Csv .\system-events.csv -NoTypeInformation -Encoding UTF8
14. Переменные, массивы и хеш-таблицы
Работать можно и короткими командами, но когда код становится длиннее, удобны переменные.
Переменные
$path = "C:\Logs"
Get-ChildItem $path
Переменные PowerShell начинаются с $.
$today = Get-Date
$limit = (Get-Date).AddDays(-30)
Массивы
$extensions = @("*.log", "*.txt", "*.csv")
foreach ($ext in $extensions) {
Get-ChildItem C:\Work -Filter $ext
}
Хеш-таблицы
Хеш-таблица — набор пар «ключ-значение».
$params = @{
Path = "C:\Logs"
Filter = "*.log"
Recurse = $true
}
Get-ChildItem @params
Такую запись через @params называют splatting. Она делает код читаемее, когда параметров становится больше.
15. Оформление результатов через PSCustomObject
Когда нужно собрать результаты исследования в табличном виде, удобен [pscustomobject].
[pscustomobject]@{
ComputerName = $env:COMPUTERNAME
UserName = $env:USERNAME
CheckedAt = Get-Date
}
Можно сформировать несколько результатов и превратить их в CSV.
Get-ChildItem C:\Logs -Filter *.log |
ForEach-Object {
[pscustomobject]@{
Name = $_.Name
FullName = $_.FullName
SizeMB = [math]::Round($_.Length / 1MB, 2)
LastWriteTime = $_.LastWriteTime
}
} |
Export-Csv .\log-files.csv -NoTypeInformation -Encoding UTF8
16. Основы файлов скриптов .ps1
Часто используемую обработку оформляйте в виде файлов .ps1.
В качестве примера создадим скрипт, который выводит список старых логов.
# Find-OldLogs.ps1
param(
[string]$Path = "C:\Logs",
[int]$Days = 30,
[string]$OutputPath = ".\old-logs.csv"
)
$limit = (Get-Date).AddDays(-$Days)
Get-ChildItem -Path $Path -Filter *.log -File -Recurse |
Where-Object { $_.LastWriteTime -lt $limit } |
Select-Object FullName, Length, LastWriteTime |
Export-Csv -Path $OutputPath -NoTypeInformation -Encoding UTF8
Write-Host "Exported: $OutputPath"
Пример запуска.
.\Find-OldLogs.ps1 -Path C:\Logs -Days 60 -OutputPath .\old-logs.csv
Если принимать аргументы через param(), условия потом проще менять.
17. Основы политики выполнения
При попытке запустить .ps1 может появиться такая ошибка.
В этой системе выполнение сценариев отключено...
В этом случае проверьте текущую политику выполнения.
Get-ExecutionPolicy
Get-ExecutionPolicy -List
Если на личной машине разработчика нужно только запускать локально созданные скрипты, чаще всего ставят RemoteSigned в области текущего пользователя.
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
Но на корпоративных ПК это может контролироваться групповой политикой. Не пытайтесь обойти это силой — уточните у администратора и по внутренним правилам.
Политика выполнения — функция безопасности, которая задаёт условия запуска скриптов в PowerShell. Но это не полноценная граница безопасности. В организации её нужно рассматривать вместе с подписью, AppLocker, Microsoft Defender, управлением правами и аудитом журналов.
18. Основы обработки ошибок
PowerShell иногда продолжает выполнение даже при возникновении ошибок.
Для важных операций используйте -ErrorAction Stop и try/catch.
try {
Copy-Item .\source.txt .\backup\source.txt -ErrorAction Stop
Write-Host "Copy succeeded"
}
catch {
Write-Error "Copy failed: $($_.Exception.Message)"
}
При обработке нескольких файлов запись сбоев позволяет отследить их позже.
$results = foreach ($file in Get-ChildItem .\input -File) {
try {
Copy-Item $file.FullName .\backup -ErrorAction Stop
[pscustomobject]@{
FileName = $file.Name
Status = "OK"
Message = ""
}
}
catch {
[pscustomobject]@{
FileName = $file.Name
Status = "NG"
Message = $_.Exception.Message
}
}
}
$results | Export-Csv .\copy-result.csv -NoTypeInformation -Encoding UTF8
19. Безопасный порядок выполнения изменяющих команд
В PowerShell важна процедура безопасной работы с изменяющими командами — удаление, перемещение, остановка.
Базовый порядок такой:
1. Посмотреть объекты через команды Get-*
2. Отфильтровать через Where-Object
3. Проверить список объектов через Select-Object
4. Записать аудиторский след через Export-Csv
5. Проверить план изменений через -WhatIf
6. Выполнить по-настоящему
Рассмотрим пример удаления файлов .tmp старше 30 дней.
Шаг 1. Посмотреть объекты
Get-ChildItem C:\Temp -Filter *.tmp -File -Recurse
Шаг 2. Отфильтровать по условию
$limit = (Get-Date).AddDays(-30)
Get-ChildItem C:\Temp -Filter *.tmp -File -Recurse |
Where-Object { $_.LastWriteTime -lt $limit }
Шаг 3. Показать только нужные столбцы
$targets = Get-ChildItem C:\Temp -Filter *.tmp -File -Recurse |
Where-Object { $_.LastWriteTime -lt $limit }
$targets |
Select-Object FullName, Length, LastWriteTime
Шаг 4. Оставить аудиторский след
$targets |
Select-Object FullName, Length, LastWriteTime |
Export-Csv .\delete-targets.csv -NoTypeInformation -Encoding UTF8
Шаг 5. Проверить через WhatIf
$targets | Remove-Item -WhatIf
Шаг 6. Выполнить
$targets | Remove-Item
Если соблюдать этот порядок, меньше аварий вида «непонятно, что было удалено».
20. Список часто используемых базовых команд
Расположение и файлы
| Цель | Пример команды |
|---|---|
| Показать текущую папку | Get-Location |
| Перейти в папку | Set-Location C:\Work |
| Показать список | Get-ChildItem |
| Показать только файлы | Get-ChildItem -File |
| Показать только папки | Get-ChildItem -Directory |
| Искать и во вложенных папках | Get-ChildItem -Recurse |
| Проверить существование | Test-Path .\file.txt |
| Создать папку | New-Item -ItemType Directory .\backup |
| Скопировать | Copy-Item .\a.txt .\backup\a.txt |
| Переместить | Move-Item .\a.txt .\archive\a.txt |
| Проверить план удаления | Remove-Item .\a.txt -WhatIf |
Обработка объектов
| Цель | Пример команды |
|---|---|
| Отфильтровать по условию | Where-Object { $_.Status -eq "Running" } |
| Отсортировать | Sort-Object LastWriteTime -Descending |
| Выбрать столбцы | Select-Object Name, LastWriteTime |
| Показать только верхние записи | Select-Object -First 10 |
| Обработать каждый элемент | ForEach-Object { $_.Name } |
| Проверить содержимое | Get-Member |
Ввод и вывод
| Цель | Пример команды |
|---|---|
| Прочитать текст | Get-Content .\app.log |
| Посмотреть конец файла | Get-Content .\app.log -Tail 50 |
| Поиск строк | Select-String -Path .\app.log -Pattern "ERROR" |
| Прочитать CSV | Import-Csv .\users.csv |
| Вывести CSV | Export-Csv .\out.csv -NoTypeInformation -Encoding UTF8 |
| Прочитать JSON | Get-Content .\a.json -Raw | ConvertFrom-Json |
| Вывести JSON | $obj | ConvertTo-Json -Depth 10 |
Исследование Windows
| Цель | Пример команды |
|---|---|
| Список процессов | Get-Process |
| Список служб | Get-Service |
| Журнал событий | Get-WinEvent -LogName System -MaxEvents 100 |
| Переменные окружения | Get-ChildItem Env: |
| Версия PowerShell | $PSVersionTable |
| Политика выполнения | Get-ExecutionPolicy -List |
21. Практический пример: разобрать логи и собрать отчёт
Рассмотрим такое требование.
Из файлов .log в C:\App\Logs, изменённых за последние 7 дней, найти строки, содержащие ERROR, и собрать их в CSV.
Не будем сразу писать готовый вариант, а построим его поэтапно.
Шаг 1. Найти файлы логов
Get-ChildItem C:\App\Logs -Filter *.log -File -Recurse
Шаг 2. Оставить файлы за последние 7 дней
$since = (Get-Date).AddDays(-7)
Get-ChildItem C:\App\Logs -Filter *.log -File -Recurse |
Where-Object { $_.LastWriteTime -ge $since }
Шаг 3. Искать ERROR
$since = (Get-Date).AddDays(-7)
Get-ChildItem C:\App\Logs -Filter *.log -File -Recurse |
Where-Object { $_.LastWriteTime -ge $since } |
Select-String -Pattern "ERROR"
Шаг 4. Вывести в CSV
$since = (Get-Date).AddDays(-7)
Get-ChildItem C:\App\Logs -Filter *.log -File -Recurse |
Where-Object { $_.LastWriteTime -ge $since } |
Select-String -Pattern "ERROR" |
Select-Object Path, LineNumber, Line |
Export-Csv .\error-report.csv -NoTypeInformation -Encoding UTF8
Шаг 5. Оформить в виде скрипта
# Export-ErrorReport.ps1
param(
[string]$LogPath = "C:\App\Logs",
[int]$Days = 7,
[string]$Pattern = "ERROR",
[string]$OutputPath = ".\error-report.csv"
)
$since = (Get-Date).AddDays(-$Days)
Get-ChildItem $LogPath -Filter *.log -File -Recurse |
Where-Object { $_.LastWriteTime -ge $since } |
Select-String -Pattern $Pattern |
Select-Object Path, LineNumber, Line |
Export-Csv $OutputPath -NoTypeInformation -Encoding UTF8
Write-Host "Exported: $OutputPath"
Пример запуска.
.\Export-ErrorReport.ps1 -LogPath C:\App\Logs -Days 14 -Pattern "ERROR|FATAL" -OutputPath .\errors.csv
22. Практический пример: архивирование старых файлов
Следующий пример — не удаление, а перемещение.
Из C:\Work\Reports переместить файлы .xlsx, которые не изменялись 90 дней и более, в C:\Work\Archive.
Проверка объектов
$source = "C:\Work\Reports"
$dest = "C:\Work\Archive"
$limit = (Get-Date).AddDays(-90)
$targets = Get-ChildItem $source -Filter *.xlsx -File |
Where-Object { $_.LastWriteTime -lt $limit }
$targets | Select-Object FullName, Length, LastWriteTime
Создание папки для архива
if (-not (Test-Path $dest)) {
New-Item -ItemType Directory -Path $dest
}
Вывод аудиторского следа
$targets |
Select-Object FullName, Length, LastWriteTime |
Export-Csv .\archive-targets.csv -NoTypeInformation -Encoding UTF8
Проверка через WhatIf
$targets | Move-Item -Destination $dest -WhatIf
Выполнение
$targets | Move-Item -Destination $dest
Если возможны совпадения имён файлов, в таком виде операция завершится ошибкой. На практике заранее договариваются о правилах: раскладывать по папкам год-месяц, добавлять дату и время к имени файла назначения, пропускать, если файл с таким именем уже есть.
23. Частые затруднения
| Симптом | Причина | Что делать |
|---|---|---|
| Команды слишком длинные, не запомнить | попытка зазубрить | искать через Get-Command, Get-Help -Examples |
Непонятно, что такое $_ |
недостаточно понимания текущего значения конвейера | запомнить в форме Where-Object { $_.Name -like "*log*" } |
| Странное содержимое CSV | Export-Csv вызывается после Format-Table |
вызывать Export-Csv после Select-Object |
| Ошибка при пробелах в пути | нет кавычек | заключить в кавычки: "C:\Work Files\a.txt" |
| Скрипт не запускается | политика выполнения | проверить через Get-ExecutionPolicy -List |
| Слишком много объектов для удаления | условие слишком широкое | сначала проверить через Select-Object FullName и -WhatIf |
| Непонятны имена свойств | не просмотрена структура объекта | использовать Get-Member |
| Искажение символов | не совпадают допущения о кодировке | проверить -Encoding при вводе/выводе и приложение, которое читает файл |
24. В каком порядке учить команды
Не нужно с самого начала запоминать все команды.
Рекомендуем такой порядок.
Этап 1. Смотреть и искать
Get-Command
Get-Help
Get-Member
Get-Location
Set-Location
Get-ChildItem
Get-Content
Select-String
Этап 2. Фильтровать и оформлять
Where-Object
Sort-Object
Select-Object
ForEach-Object
Format-Table
Format-List
Этап 3. Ввод и вывод
Import-Csv
Export-Csv
ConvertFrom-Json
ConvertTo-Json
Set-Content
Add-Content
Out-File
Этап 4. Изменение
New-Item
Copy-Item
Move-Item
Rename-Item
Remove-Item
Start-Service
Stop-Service
Restart-Service
Stop-Process
Изменяющие команды всегда изучайте в паре с проверочными.
# Смотреть
Get-ChildItem .\logs -Filter *.tmp
# Смотреть план удаления
Get-ChildItem .\logs -Filter *.tmp | Remove-Item -WhatIf
# Выполнить
Get-ChildItem .\logs -Filter *.tmp | Remove-Item
25. Практический эксплуатационный чек-лист
Когда PowerShell используют в рабочих задачах, безопаснее заранее проверить следующее.
- проверено, какой PowerShell запускается —
powershell.exeилиpwsh.exe; - версия проверена через
$PSVersionTable; - перед изменением объекты выведены через команды
Get-*; - условия
Where-Objectпроверены на экране; - перед удалением, перемещением или остановкой использован
-WhatIf; - список объектов перед выполнением сохранён в CSV;
- в рабочей среде заранее проверены резервное копирование или процедура восстановления;
- проверены политика выполнения скрипта и внутренние правила;
- подготовлен вывод логов на случай ошибки;
- в общих скриптах использованы полные имена команд, а не псевдонимы.
26. Итог
Основа PowerShell — не запоминание огромного числа команд. На практике окупается такая схема:
искать через Get-Command
смотреть способ использования через Get-Help
проверять свойства через Get-Member
смотреть объекты через Get-*
отфильтровать через Where-Object
оформить столбцы через Select-Object
оставить аудиторский след через Export-Csv
проверить план изменений через -WhatIf
выполнять в последнюю очередь
PowerShell — мощная среда: она умеет удалять файлы, останавливать службы, завершать процессы и даже работать с реестром. Именно поэтому первым делом стоит выучить не «опасные команды», а «процедуру, которой безопасно подтверждают объекты».
смотреть → отфильтровать → записать → сделать пробный прогон → выполнить
Если соблюдать этот порядок, PowerShell перестаёт быть просто «чёрным экраном» и становится практичным инструментом, которым наводят порядок в задачах Windows, исследуют их и автоматизируют.
Справочные ссылки
- Полный набор примеров кода к этой статье (скрипты по темам, тесты Pester) - komurasoft-blog-samples (GitHub)
- PowerShell Documentation - Microsoft Learn
- Installing PowerShell 7 on Windows - Microsoft Learn
- Differences between Windows PowerShell 5.1 and PowerShell 7.x - Microsoft Learn
- Get-Command - Microsoft Learn
- Get-Help - Microsoft Learn
- Get-Member - Microsoft Learn
- about_Pipelines - Microsoft Learn
- Where-Object - Microsoft Learn
- Select-Object - Microsoft Learn
- Get-Process - Microsoft Learn (есть описание столбцов по умолчанию)
- Get-WinEvent - Microsoft Learn
- about_Character_Encoding (Windows PowerShell 5.1) - Microsoft Learn
- Import-Csv - Microsoft Learn
- Export-Csv - Microsoft Learn
- about_Execution_Policies - Microsoft Learn
Похожие статьи
- Практические команды PowerShell — мелкие приёмы для повседневной работы
- Кодировки текста и переводы строк в Windows
- Гид по подготовке VBA и внутренних инструментов к отказу от VBScript
- Ловушки регистрации и bitness при разработке COM/OCX/ActiveX
Услуги, связанные с этой темой
Разработка Windows-приложений
Мы поддерживаем разработку Windows-ПО: бизнес-приложения, интеграцию с оборудованием, коммуникационные инструменты.
Посмотреть услугу / Связаться с нами
Использование и миграция существующих активов
Мы поддерживаем инвентаризацию, доработку и миграцию существующих активов, включая старые пакетные файлы, VBScript, VBA, PowerShell, COM / ActiveX.
Похожие статьи
Недавние статьи с теми же тегами помогут подробнее изучить близкие темы.
Практические команды PowerShell — мелкие приёмы для повседневной работы
Разбираем практические команды PowerShell для повседневной работы: где применять Measure-Object, Group-Object, Select-String, Compare-Obj...
PowerShell на практике — безопасная автоматизация анализа логов, архивирования и отчётов
Разбираем практический порядок безопасной работы со скриптами PowerShell: анализ логов, CSV-отчёты, архивирование старых логов, сохранени...
Обработка ошибок и retry в PowerShell — от ловушки нерабочего try/catch до exit code и типовых схем повтора
На практике разбираем различие завершающих и незавершающих ошибок PowerShell, ловушку, из-за которой не срабатывает try/catch, стандартны...
Политика выполнения PowerShell и подпись скриптов — как отказаться от Bypass в роли постоянной заглушки
Политика выполнения PowerShell — не граница безопасности, а защитный механизм. В статье разобраны различия RemoteSigned и других политик,...
Как запустить PowerShell из C# (CSharp) и получить результат в виде объектов
Разбираем, как запустить PowerShell из C# и получить результат не строкой, а как PSObject: PowerShell SDK, AddCommand, AddParameter, Base...
Связанные темы
Эти страницы показывают тему статьи в более широком контексте услуг и решений.
Технические темы Windows
Раздел о разработке Windows, расследовании сбоев и использовании существующих активов.
Услуги по этой теме
Статья напрямую связана со следующими услугами.
Разработка приложений для Windows
Бизнес-приложения, интеграция оборудования и средства связи — от требований до разработки.
Частые вопросы
Вопросы, которые часто возникают при консультациях по теме статьи.
- С чего начать изучение PowerShell?
- Не с запоминания команд, а с того, как их искать. Важны три вещи: умение находить команды через Get-Command и Get-Help, умение передавать результат следующей команде через конвейер (|), и привычка проверять последствия через -WhatIf или -Confirm перед удалением, остановкой или изменением. Если непонятно имя свойства объекта, содержимое можно посмотреть через Get-Member. Базовый порядок: «искать → смотреть → отфильтровать → отсортировать → вывести → при необходимости изменить».
- Чем PowerShell отличается от командной строки?
- Главное отличие в том, что вывод командной строки — это в основном строки текста, а вывод PowerShell — объекты. Например, файл представлен как объект со свойствами Name, Length, LastWriteTime и другими, поэтому фильтрация через Where-Object и сортировка через Sort-Object пишутся естественно. Имена команд тоже унифицированы в форме «глагол-существительное», например Get-ChildItem или Copy-Item, поэтому незнакомые команды проще искать.
- Что использовать — Windows PowerShell 5.1 или PowerShell 7.x?
- Если изучаете с нуля, ориентироваться на PowerShell 7.x (pwsh.exe) вполне можно. Но старые внутренние управляющие скрипты и модули, специфичные для Windows, иногда рассчитаны именно на Windows PowerShell 5.1 (powershell.exe). На практике сначала проверьте версию через $PSVersionTable, а для скриптов, которым нужна определённая минимальная версия, в начале файла укажите условие вроде #Requires -Version 7.0 — так меньше аварий.
- Как в PowerShell безопасно выполнять удаление и изменения?
- Соблюдать порядок «смотреть → отфильтровать → записать → сделать пробный прогон → выполнить». Конкретно: сначала вывести объекты командами Get-*, отфильтровать через Where-Object, проверить список через Select-Object, сохранить аудиторский след в CSV через Export-Csv, проверить план изменений через -WhatIf и только после этого выполнить операцию по-настоящему. PowerShell позволяет вести исследование и менять систему на одном и том же экране, поэтому важна привычка начинать с проверок, доступных только для чтения.
Об авторе
Страница с профилем автора статьи.
Го Комура
Представитель KomuraSoft LLC
Специализируется на разработке программного обеспечения для Windows, техническом консалтинге и расследовании сбоев, особенно в проектах с унаследованными системами и трудно воспроизводимыми ошибками.