Практические команды PowerShell — мелкие приёмы для повседневной работы
· Обновлено: · Го Комура · PowerShell, Windows, Командная строка, Автоматизация, Повышение эффективности, Использование существующих активов
История изменений (1 обновлений, последнее 30 Aug 2026)
Журнал изменений этой статьи. Там, где версия до правки была заархивирована, она остаётся доступной для чтения по постоянной ссылке с DOI.
- Русский текст переписан как полноценный технический перевод, а не калька с японского. Утверждения статьи не менялись.
- Первая публикация
Цитирование статьи(DOI (зарегистрированный архив): 10.5281/zenodo.21619869)
Приведённые ниже DOI относятся к ранее зарегистрированным архивным версиям, которые могут отличаться от текущего текста. Для ссылки на текущий текст используйте URL этой страницы.
Го Комура (2026). Практические команды PowerShell — мелкие приёмы для повседневной работы. KomuraSoft LLC. https://comcomponent.com/ru/blog/2026/06/02/002-powershell-practical-command-recipes/
- DOI (зарегистрированный архив)
- 10.5281/zenodo.21619869
- DOI (последняя зарегистрированная версия)
- 10.5281/zenodo.21619870
1. Что стоит понять в первую очередь
Освоив основы PowerShell, дальше имеет смысл наращивать набор мелких приёмов, которые часто нужны в работе, — тогда повседневные задачи решаются проще.
«Мелкие приёмы» здесь — не короткие псевдонимы. В этой статье вместо сокращений вроде ls и cat используются полные имена командлетов: Get-ChildItem, Get-Content, Select-String.
На этой основе следующие задачи должны получаться одной или несколькими строками:
Посчитать количество
Узнать суммарный размер
Убрать дубликаты
Сгруппировать по типам
Достать только нужные значения
Сравнить два набора результатов
Посмотреть строки вокруг найденной в логе
Отправить результат в буфер обмена
Сохранить вывод и одновременно показать его на экране
Проверить переменные окружения и сеть
PowerShell полезен и без длинных скриптов. Сначала расширьте набор часто используемых блоков, чтобы в повседневной работе их можно было понемногу комбинировать.
Важнее не зубрить команды, а в нужный момент вспоминать: «для этой задачи подходит вот этот блок».
Код из статьи опубликован на GitHub как готовый к запуску набор примеров, разложенный по темам в соответствии с главами (скрипты-рецепты и тесты Pester).
powershell-practical-command-recipes - komurasoft-blog-samples (GitHub)
Чем эта статья отличается от предыдущей
Эта статья продолжает Основы команд PowerShell — операции, которые стоит выучить первыми, и как использовать их безопасно. Роли разделены так:
| Основы команд PowerShell | Эта статья | |
|---|---|---|
| Цель | Начать работать в PowerShell | Научиться считать, группировать, сравнивать извлечённые результаты и сохранять их |
| В центре | Синтаксис и конвейер, поиск команд | Блоки для подсчёта, сравнения, выборки и вывода |
| CSV / JSON | Базовое чтение и запись | Фильтрация уже загруженных данных и их агрегация |
| Процессы / службы / журнал событий | Как получить список | Как посчитать полученный список по типам и снять разницу |
| Изменяющие команды | Сам безопасный порядок выполнения | Команды разбора и сохранения копий, которые встраиваются в этот порядок |
Короче: предыдущая статья доводит до «как достать значения», эта — «что с ними делать дальше».
Основы команд получения вроде Get-ChildItem, Get-Content, Import-Csv, Get-Service, политика выполнения, написание .ps1 и обработка ошибок — в предыдущей статье. Здесь мы на это опираемся и идём дальше. Темы вроде «Format-* ставить в конец» и Export-Csv -Encoding UTF8 встречаются в обеих статьях, но здесь они рассматриваются под углом «как подготовить данные к подсчёту и сравнению».
На схеме сплошная линия обозначает отношение, которое выполняется всегда, а пунктирная — условное отношение (условия указаны в пояснении к каждому отношению на странице сведений). Полный список отношений (всего 26, с доказательствами и степенью уверенности) и определения основных понятий собраны на странице сведений карты знаний (на японском). Данные: JSON-LD / Turtle
2. Подход в этой статье
Три исходные предпосылки:
- Команды писать полными именами
- Опираться в основном на команды, которые только читают данные
- Изменяющие команды всегда рассматривать вместе с проверкой объектов и
-WhatIf
Например, безопаснее не учить сразу команду удаления файлов, а сначала освоить такой порядок:
Посмотреть объекты
→ отфильтровать по условию
→ посчитать
→ при необходимости сохранить в CSV
→ проверить, что именно изменится
→ выполнить
В этой статье в центре не сильные операции вроде удаления и остановки, а разбор, подсчёт, сравнение и вывод.
3. Карта часто используемых команд
Основные команды, которые понадобятся. В правом столбце — главы, где они разбираются подробнее.
| Что нужно сделать | Команда | Глава |
|---|---|---|
| Посчитать количество или сумму | Measure-Object |
4, 5 |
| Достать только нужные значения | Select-Object -ExpandProperty |
6 |
| Убрать дубликаты | Sort-Object -Unique |
7 |
| Сгруппировать по типам | Group-Object |
8 |
| Вывести нужные столбцы и добавить вычисляемые | Select-Object |
9 |
| Отсортировать | Sort-Object |
10 |
| Искать строки | Select-String |
12 |
| Сравнить два набора результатов | Compare-Object |
14 |
| Посчитать хеш | Get-FileHash |
15 |
| Работать с буфером обмена | Set-Clipboard / Get-Clipboard |
16 |
| Вывести и на экран, и в файл | Tee-Object |
17 |
| Сохранить журнал работы | Start-Transcript |
18 |
| Проверить сетевую доступность | Test-Connection / Test-NetConnection |
26 |
| Измерить время выполнения | Measure-Command |
28 |
| Посмотреть детали ошибки | Get-Error |
31 |
| Обработать каждый элемент | ForEach-Object |
по ходу глав |
Учить всё сразу не нужно. Удобнее запоминать в паре с целью: «посчитать — Measure-Object», «сгруппировать — Group-Object», «сравнить — Compare-Object».
Карта глав по задачам
Главы с 4-й по 36-ю сгруппированы так. Можно начинать с нужного места.
| Категория | Главы | О чём речь |
|---|---|---|
| Подсчёт и подготовка вывода | 4–11 | Количество, сумма, максимум и среднее, выборка значений, удаление дубликатов, группировка по типам, вычисляемые столбцы, сортировка, место Format-* |
| Текст и разбор логов | 12–14 | Поиск строк и соседний контекст, замена, сравнение двух списков |
| Содержимое файлов и данных | 15, 19, 20 | Проверка хеша, фильтрация CSV, значения в JSON |
| Вывод и копии для отчёта | 16–18 | Буфер обмена, одновременный вывод на экран и в файл, журнал работы |
| Разбор системы | 21–25, 31 | Переменные окружения, профиль, процессы, службы, журнал событий, детали ошибок |
| Сеть | 26, 27 | Проверка доступности, ответы Web |
| Как выполнять | 28–30 | Замер времени, фоновый запуск, история команд |
| Напоминание по синтаксису | 32 | Операторы сравнения |
| Готовые рецепты | 33, 34 | 11 рабочих рецептов и оговорки при сочетании с изменяющими командами |
| Шпаргалка | 35 | Таблица, чтобы вспоминать команду по задаче |
Если задача ясна, а команда не вспоминается, быстрее всего начать со шпаргалки в главе 35.
4. Посчитать количество — Measure-Object
Самая частая операция — посчитать количество.
Число файлов в текущей папке:
Get-ChildItem . -File | Measure-Object
Чтобы захватить и вложенные папки:
Get-ChildItem . -File -Recurse | Measure-Object
Count в результате Measure-Object — это и есть количество.
Чтобы увидеть суммарный размер файлов, агрегируйте Length.
Get-ChildItem . -File -Recurse |
Measure-Object -Property Length -Sum
В таком виде это байты, человеку читать неудобно, поэтому переведём в гигабайты.
$size = Get-ChildItem . -File -Recurse |
Measure-Object -Property Length -Sum
[math]::Round($size.Sum / 1GB, 2)
Так удобно примерно оценить размер папки целиком.
5. Заодно смотрим максимум и среднее
Measure-Object умеет не только сумму, но и максимум со средним.
Get-ChildItem . -File |
Measure-Object -Property Length -Sum -Average -Maximum -Minimum
Так смотрят разброс размеров файлов.
Можно просуммировать и накопительное процессорное время процессов. Свойство CPU у Get-Process — это не текущая загрузка, а число секунд процессорного времени с момента запуска процесса.
Get-Process |
Measure-Object -Property CPU -Sum
Это накопительное значение, а не мгновенная загрузка CPU, поэтому оно зависит от момента запуска команды и от того, как долго процессы уже работают.
Для разбора этого достаточно. Для строгого мониторинга нужны отдельные средства наблюдения и продуманная схема журналирования.
6. Достать только значения — Select-Object -ExpandProperty
Select-Object чаще всего используют, чтобы выбрать столбцы.
Get-Process |
Select-Object Name, Id, CPU
Это даёт «объекты со столбцами Name, Id и CPU».
Если нужны только значения, используйте -ExpandProperty.
Get-Process -Name notepad -ErrorAction SilentlyContinue |
Select-Object -ExpandProperty Id
То же самое, когда нужны только имена файлов.
Get-ChildItem . -File |
Select-Object -ExpandProperty Name
Когда результат команды нужно передать другой команде или в текстовый файл, -ExpandProperty удобен.
Например, сохраним только список имён файлов.
Get-ChildItem . -File |
Select-Object -ExpandProperty Name |
Set-Content .\file-names.txt -Encoding UTF8
Select-Object Name и Select-Object -ExpandProperty Name похожи, но форма результата разная.
Select-Object Name
→ таблица со столбцом Name
Select-Object -ExpandProperty Name
→ сами значения Name
Если результат уходит в CSV, лучше оставить столбец. Если его нужно передать в дальнейшую обработку строк — удобнее просто значения.
7. Убрать дубликаты — Sort-Object -Unique
Допустим, нужен список только расширений файлов.
Get-ChildItem . -File |
Select-Object -ExpandProperty Extension |
Sort-Object -Unique
На выходе останутся только уникальные расширения, например .txt, .log, .csv.
Так же можно посмотреть только уникальные имена процессов.
Get-Process |
Select-Object -ExpandProperty ProcessName |
Sort-Object -Unique
Пример: из CSV со списком пользователей достать только названия отделов.
Import-Csv .\users.csv |
Select-Object -ExpandProperty Department |
Sort-Object -Unique
Когда в списке много одинаковых значений и читать его тяжело, первым делом вспоминайте Sort-Object -Unique.
8. Сгруппировать по типам — Group-Object
Если нужно не просто убрать дубликаты, а увидеть «чего сколько», используйте Group-Object.
Посчитаем файлы по расширениям.
Get-ChildItem . -File |
Group-Object -Property Extension -NoElement |
Sort-Object -Property Count -Descending
Вывод выглядит так. Числа и расширения зависят от содержимого папки, порядок столбцов один и тот же.
Count Name
----- ----
42 .log
18 .csv
7 .txt
3
Строка с пустым Name — файлы без расширения.
Если убрать -NoElement, появляется столбец Group, и в нём видны сами элементы группы.
Count Name Group
----- ---- -----
42 .log {app-20260601.log, app-20260602.log, app-20260603.log...}
18 .csv {export-01.csv, export-02.csv, export-03.csv...}
Когда нужны только числа, столбец Group забивает экран — поэтому добавляют -NoElement. Если нужно увидеть, что именно попало в группу, параметр не ставят.
Посчитаем службы по состоянию.
Get-Service |
Group-Object -Property Status -NoElement
Посчитаем записи журнала событий по уровню.
Get-WinEvent -LogName System -MaxEvents 500 |
Group-Object -Property LevelDisplayName -NoElement
Group-Object хорошо подходит, чтобы в начале разбора увидеть общую картину.
Каких расширений больше всего
Служб в каком состоянии больше всего
Каких уровней ошибок больше всего
В каком отделе больше всего данных
Используйте его, когда сначала хочется увидеть распределение, а не сразу лезть в детали.
9. Собрать нужные столбцы — добавить вычисляемые
Размер файла доступен через Length, но единица — байты. Смотреть сырые байты каждый раз утомительно, поэтому удобно завести столбец, пересчитанный в МБ или КБ.
Get-ChildItem . -File |
Select-Object Name, @{Name="SizeKB"; Expression={ [math]::Round($_.Length / 1KB, 1) }}, LastWriteTime
Пример с вложенными папками: сначала самые большие файлы.
Get-ChildItem . -File -Recurse |
Sort-Object -Property Length -Descending |
Select-Object -First 20 FullName, @{Name="SizeMB"; Expression={ [math]::Round($_.Length / 1MB, 2) }}, LastWriteTime
@{Name="..."; Expression={ ... }} — синтаксис вычисляемого столбца. Поначалу запись кажется длинной, но на практике её используют постоянно.
Например, так можно показать использование памяти процессом в МБ.
Get-Process |
Sort-Object -Property WorkingSet -Descending |
Select-Object -First 10 Name, Id, @{Name="MemoryMB"; Expression={ [math]::Round($_.WorkingSet / 1MB, 1) }}
В отчёте столбец вроде SizeMB читается гораздо лучше исходного Length.
10. Смотреть от новых к старым, от старых к новым, от больших к меньшим
В PowerShell сортировка — это Sort-Object.
Недавно изменённые файлы:
Get-ChildItem . -File |
Sort-Object -Property LastWriteTime -Descending |
Select-Object -First 10 Name, LastWriteTime
Старые файлы:
Get-ChildItem . -File |
Sort-Object -Property LastWriteTime |
Select-Object -First 10 Name, LastWriteTime
Большие файлы:
Get-ChildItem . -File -Recurse |
Sort-Object -Property Length -Descending |
Select-Object -First 10 FullName, Length
Эти три варианта используют постоянно.
От новых к старым → LastWriteTime -Descending
От старых к новым → LastWriteTime
От больших к меньшим → Length -Descending
Это частые спутники при разборе логов, уборке лишних файлов и проверке места на диске.
11. Format-* — только в конце, для экрана
Чтобы вывод на экране читался лучше, используют Format-Table и Format-List.
Get-Process |
Sort-Object -Property WorkingSet -Descending |
Select-Object -First 10 Name, Id, WorkingSet |
Format-Table -AutoSize
Для подробностей по одному объекту удобен Format-List.
Get-Process -Id $PID |
Format-List *
Но Format-Table и Format-List — «для отображения».
Перед выводом в CSV и перед следующей командой, которая ещё будет обрабатывать данные, их лучше не ставить.
# Избегать
Get-Process |
Format-Table Name, Id |
Export-Csv .\process.csv -NoTypeInformation
Для CSV выбирайте столбцы через Select-Object.
# Правильно
Get-Process |
Select-Object Name, Id |
Export-Csv .\process.csv -NoTypeInformation -Encoding UTF8
Если сомневаетесь, рассуждайте так:
Только посмотреть на экране → Format-Table / Format-List
Результат ещё понадобится → Select-Object
12. Поиск по логам чуть удобнее — Select-String
Для поиска строк используют Select-String.
Select-String -Path .\logs\*.log -Pattern "ERROR"
Можно указать сразу несколько шаблонов.
Select-String -Path .\logs\*.log -Pattern "ERROR", "WARN", "FATAL"
Чтобы увидеть соседние строки, используйте -Context.
Select-String -Path .\logs\*.log -Pattern "ERROR" -Context 2
Это дополнительно показывает две строки до и после найденной — удобно, когда нужно понять, что происходило вокруг ошибки.
Чтобы искать буквальную строку, используйте -SimpleMatch.
Select-String -Path .\logs\*.log -Pattern "[ERROR]" -SimpleMatch
-Pattern в Select-String по умолчанию считается регулярным выражением. Если нужно искать такие символы, как [ или ., буквально, -SimpleMatch делает намерение явным.
Поиск с учётом регистра:
Select-String -Path .\logs\*.log -Pattern "Error" -CaseSensitive
Результаты поиска тоже можно сохранить в CSV.
Select-String -Path .\logs\*.log -Pattern "ERROR" |
Select-Object Path, LineNumber, Line |
Export-Csv .\error-lines.csv -NoTypeInformation -Encoding UTF8
13. Замена строк
Чтобы заменить часть строки, используют -replace.
"server01.example.com" -replace "\.example\.com$", ""
Если меняете содержимое файла, безопаснее не перезаписывать исходник сразу. Сначала выведите результат в отдельный файл.
(Get-Content .\appsettings.json -Raw) -replace "localhost", "db01" |
Set-Content .\appsettings.preview.json -Encoding UTF8
После проверки при необходимости перенесите изменения в исходный файл.
В конфигурационных файлах и массовых заменах слишком много совпадений легко приводит к ошибке. Безопаснее сначала проверить объекты через Select-String и только потом заменять.
Select-String -Path .\appsettings.json -Pattern "localhost" -SimpleMatch
14. Сравнить два результата — Compare-Object
Compare-Object показывает различия между двумя списками.
Когда это нужно: чтобы проверить, что состав не изменился до и после работы; чтобы сверить настройки или список установленного ПО на двух ПК; чтобы сравнить набор служб в продакшене и на стенде. Команда как раз для случая «должно было остаться как было».
Например, сравним списки имён файлов до и после изменений.
Compare-Object `
-ReferenceObject (Get-Content .\before.txt) `
-DifferenceObject (Get-Content .\after.txt)
Если в before.txt лежат a.log, b.log, c.log, а в after.txt — b.log, c.log, d.log, вывод будет таким:
InputObject SideIndicator
----------- -------------
d.log =>
a.log <=
b.log и c.log, которые есть в обоих списках, по умолчанию не показываются. На экран попадают только различия.
Значения SideIndicator такие:
| Отображение | Значение |
|---|---|
<= |
Есть только слева, то есть в ReferenceObject |
=> |
Есть только справа, то есть в DifferenceObject |
== |
Есть в обоих. Появляется, если указать -IncludeEqual |
Стрелку проще запомнить так: она «тянется» к той стороне, где объект есть — к ReferenceObject (слева) или к DifferenceObject (справа). В примере выше a.log есть только слева (до изменения), значит файл исчез; d.log есть только справа (после изменения), значит файл появился.
Пример: сохранить списки имён файлов из папок и сравнить их.
Get-ChildItem .\before -File |
Select-Object -ExpandProperty Name |
Set-Content .\before-list.txt -Encoding UTF8
Get-ChildItem .\after -File |
Select-Object -ExpandProperty Name |
Set-Content .\after-list.txt -Encoding UTF8
Compare-Object `
-ReferenceObject (Get-Content .\before-list.txt) `
-DifferenceObject (Get-Content .\after-list.txt)
Можно посмотреть и изменения в списке служб.
Get-Service |
Select-Object Name, Status |
Export-Csv .\services-before.csv -NoTypeInformation -Encoding UTF8
После изменения выведите ещё раз.
Get-Service |
Select-Object Name, Status |
Export-Csv .\services-after.csv -NoTypeInformation -Encoding UTF8
Сравним.
Compare-Object `
-ReferenceObject (Import-Csv .\services-before.csv) `
-DifferenceObject (Import-Csv .\services-after.csv) `
-Property Name, Status
Если после каждой задачи сохранять разницу «до / после», разбор и отчётность становятся проще.
15. Проверить хеш файла — Get-FileHash
Когда нужно убедиться, что скачанный или распространяемый файл совпадает с оригиналом, используют хеш.
Get-FileHash .\installer.exe -Algorithm SHA256
Пример: проверить все файлы в папке разом.
Get-ChildItem .\downloads -File |
ForEach-Object { Get-FileHash -LiteralPath $_.FullName -Algorithm SHA256 }
Результаты можно сохранить и в CSV.
Get-ChildItem .\downloads -File |
ForEach-Object { Get-FileHash -LiteralPath $_.FullName -Algorithm SHA256 } |
Select-Object Path, Hash |
Export-Csv .\hashes.csv -NoTypeInformation -Encoding UTF8
Файлы, которые по имени выглядят одинаково, по содержимому могут различаться. Для дистрибутивов, резервных копий и переносов сохранённые хеши заметно упрощают проверку.
16. Отправить в буфер обмена — Set-Clipboard
Когда это нужно: когда результат разбора нужно сразу вставить в ответ на запрос или в отчёт об инциденте, либо вставить в Excel как таблицу. Весь путь «создать файл → открыть → выделить → скопировать» просто выпадает.
Если результат команды нужно вставить в письмо или чат, удобно отправить его в буфер обмена.
Get-Service |
Select-Object Name, Status |
ConvertTo-Csv -NoTypeInformation |
Set-Clipboard
Чтобы посмотреть содержимое буфера обмена:
Get-Clipboard
Чтобы вставить в Excel с разделителем-табуляцией, задайте разделитель ConvertTo-Csv как табуляцию.
Get-Process |
Select-Object Name, Id, CPU |
ConvertTo-Csv -NoTypeInformation -Delimiter "`t" |
Set-Clipboard
Если результат нужен только на время, это проще, чем каждый раз создавать файл. Если нужна постоянная копия, сохраните её через Export-Csv.
17. Показать на экране и сохранить в файл — Tee-Object
Когда результат нужно видеть на экране и одновременно сохранять в файл, используют Tee-Object.
Get-Process |
Sort-Object -Property WorkingSet -Descending |
Select-Object -First 10 Name, Id, WorkingSet |
Tee-Object -FilePath .\top-process.txt
Tee-Object направляет результат конвейера в двух направлениях.
Вывести на экран
Дополнительно сохранить в файл
Это подходит для сценария «смотреть и одновременно фиксировать» во время разбора. Если потом нужно открыть результат в Excel, удобнее Export-Csv.
Get-Process |
Sort-Object -Property WorkingSet -Descending |
Select-Object -First 10 Name, Id, WorkingSet |
Export-Csv .\top-process.csv -NoTypeInformation -Encoding UTF8
Проще запомнить так: для экрана — Tee-Object, чтобы сохранить таблицу — Export-Csv.
18. Сохранить журнал работы — Start-Transcript
Когда это нужно: при работе в продакшене, когда потом придётся отчитаться, какие команды и в каком порядке выполнялись. Это копия для отчёта при разборе инцидента или обслуживании: команду стоит дать один раз до начала работы.
Чтобы записать последовательность действий, используют Start-Transcript.
Start-Transcript -Path .\work-log.txt
После этого записываются выполняемые команды и вывод на экран.
Завершение:
Stop-Transcript
Во время разбора позже часто хочется проверить следующее:
Какие команды выполнялись
В какой папке шла работа
Какие получились результаты
Были ли ошибки
Start-Transcript подстраховывает, если рабочие заметки вы забыть. Но если на экран в ходе работы попадают данные, которые нельзя записывать, — пароли, токены — пользуйтесь осторожно.
19. Прочитать CSV и отфильтровать по условию
В рабочих данных CSV встречается постоянно.
Например, предположим, что есть такой файл users.csv.
Name,Department,Enabled
Suzuki,Sales,true
Tanaka,Accounting,false
Sato,Sales,true
Загрузка:
Import-Csv .\users.csv
Посмотрим только людей из отдела Sales.
Import-Csv .\users.csv |
Where-Object { $_.Department -eq "Sales" }
Выведем только активных пользователей в отдельный CSV.
Import-Csv .\users.csv |
Where-Object { $_.Enabled -eq "true" } |
Export-Csv .\enabled-users.csv -NoTypeInformation -Encoding UTF8
Значения из CSV чаще всего трактуются как строки, поэтому при сравнении true / false или чисел при необходимости учитывайте преобразование типов.
Например, только строки с баллом от 80:
Import-Csv .\scores.csv |
Where-Object { [int]$_.Score -ge 80 }
20. Посмотреть значения конфигурации JSON
JSON часто встречается в конфигурационных файлах и веб-API.
$config = Get-Content .\settings.json -Raw | ConvertFrom-Json
$config
Можно посмотреть и конкретное значение.
$config.Database.Host
Пример: изменить значение и сохранить в отдельный файл.
$config.Database.Host = "db01"
$config |
ConvertTo-Json -Depth 10 |
Set-Content .\settings.updated.json -Encoding UTF8
При работе с JSON часто используют Get-Content -Raw. С -Raw весь файл читается как одна строка — для многострочного JSON так понятнее.
21. Посмотреть переменные окружения
Переменные окружения часто нужны для настроек приложений и проверки путей.
Список:
Get-ChildItem Env:
Текущее имя пользователя:
$env:USERNAME
Временная папка:
$env:TEMP
Разбить PATH, чтобы было удобнее читать:
$env:PATH -split ";"
Задать переменную окружения только для текущего сеанса PowerShell:
$env:APP_MODE = "Development"
Эта настройка действует только внутри текущего открытого сеанса PowerShell.
Чтобы сохранить как пользовательскую переменную окружения, сделайте так.
[Environment]::SetEnvironmentVariable("APP_MODE", "Development", "User")
Это операция, которая меняет окружение, поэтому на корпоративных ПК и в продакшене сначала проверьте область влияния.
22. Проверить профиль
В PowerShell есть профиль, который загружается при запуске.
Проверим расположение.
$PROFILE
Проверим, существует ли он.
Test-Path $PROFILE
Создание:
New-Item -ItemType File -Path $PROFILE -Force
Открыть в Блокноте:
notepad $PROFILE
В профиле удобно хранить часто используемые настройки и функции. Но если написать там слишком сложную логику, PowerShell будет дольше запускаться, а воспроизвести это в другой среде станет сложнее, поэтому сначала лучше ограничиться часто используемыми путями и настройками отображения.
23. Посмотреть процессы
При разборе процессов чаще всего сначала смотрят по убыванию использования памяти.
Get-Process |
Sort-Object -Property WorkingSet -Descending |
Select-Object -First 10 Name, Id, @{Name="MemoryMB"; Expression={ [math]::Round($_.WorkingSet / 1MB, 1) }}
Отфильтровать по конкретному имени:
Get-Process -Name notepad -ErrorAction SilentlyContinue
Процесс не останавливайте сразу — сначала проверьте через -WhatIf.
Stop-Process -Name notepad -WhatIf
Если всё в порядке, выполняйте.
Stop-Process -Name notepad
В продакшене остановка процесса может затронуть работу. Перед остановкой проверьте объект, кто им пользуется и как восстанавливаться.
24. Посмотреть службы
Список служб:
Get-Service
Только остановленные службы:
Get-Service |
Where-Object { $_.Status -eq "Stopped" }
Найти службы с автоматическим запуском, которые при этом остановлены:
Get-Service |
Where-Object { $_.StartType -eq "Automatic" -and $_.Status -ne "Running" } |
Select-Object Name, DisplayName, Status, StartType
При перезапуске службы тоже сначала проверьте объект.
Get-Service -Name "Spooler"
Пробный прогон:
Restart-Service -Name "Spooler" -WhatIf
Операции со службами сильно влияют на систему, поэтому перед выполнением проверьте окно обслуживания и процедуру восстановления.
25. Посмотреть журнал событий
При разборе Windows часто приходится смотреть журнал событий.
Последние 100 записей журнала System:
Get-WinEvent -LogName System -MaxEvents 100 |
Select-Object TimeCreated, ProviderName, Id, LevelDisplayName, Message
Только ошибки и предупреждения:
Get-WinEvent -LogName System -MaxEvents 500 |
Where-Object { $_.LevelDisplayName -in @("Error", "Warning") } |
Select-Object TimeCreated, ProviderName, Id, LevelDisplayName, Message
Только ошибки за последние 24 часа:
$start = (Get-Date).AddHours(-24)
Get-WinEvent -FilterHashtable @{ LogName = "System"; StartTime = $start } |
Where-Object { $_.LevelDisplayName -eq "Error" } |
Select-Object TimeCreated, ProviderName, Id, 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
Журнал событий легко разрастается, поэтому диапазон важно ограничивать через -MaxEvents или указанием периода.
26. Проверить сеть
Для проверки доступности используют Test-Connection.
Test-Connection example.com -Count 4
Чтобы в Windows проверить доступность TCP-порта, удобен Test-NetConnection.
Test-NetConnection example.com -Port 443
Проверка разрешения DNS:
Resolve-DnsName example.com
При разборе сети проверку дробят так:
Разрешается ли имя
Достижим ли IP
Открыт ли нужный порт
Не мешают ли прокси или брандмауэр
Не пытайтесь судить обо всём только средствами PowerShell — удобнее использовать его как точку входа и идти по шагам.
27. Посмотреть результаты из веба
Чтобы получить веб-страницу, используют Invoke-WebRequest.
Invoke-WebRequest https://example.com |
Select-Object StatusCode, StatusDescription
Для результатов JSON API удобен Invoke-RestMethod.
Invoke-RestMethod https://api.github.com/repos/PowerShell/PowerShell |
Select-Object full_name, stargazers_count, forks_count
Ответ API чаще всего сразу можно обрабатывать как объекты PowerShell, и это хорошо сочетается с Select-Object и Where-Object.
При разборе внутренних API тоже начинайте с запросов на чтение (GET).
Если в запросе есть учётные данные или токены, следите за тем, что попадает на экран и в транскрипт.
28. Измерить время выполнения — Measure-Command
Когда это нужно: чтобы решить, можно ли ставить обработку в ночной пакет, или чтобы сравнить, стала ли новая запись быстрее. Решение опирается на цифры, а не на ощущение.
Когда нужно узнать, сколько времени занимает обработка, используют Measure-Command.
Measure-Command {
Get-ChildItem C:\Windows -File -Recurse -ErrorAction SilentlyContinue |
Measure-Object
}
В результате есть TotalSeconds и TotalMilliseconds.
$result = Measure-Command {
Get-ChildItem . -File -Recurse | Measure-Object
}
$result.TotalSeconds
Когда скрипт нужно ускорить, важно измерять время, а не полагаться на ощущения. Но результат зависит от числа файлов, состояния диска и сети, поэтому не судите по одному запуску — проверьте несколько раз.
29. Долгие операции в фоне — Start-Job
Когда это нужно: когда полный обход большой папки или подсчёт хешей занимает минуты, и за это время хочется продолжить другой разбор. Обратное тоже верно: выносить в задание операцию на несколько секунд обычно невыгодно — дороже сам запуск.
Чтобы выполнить долгий разбор отдельным заданием, используют Start-Job.
$job = Start-Job -ScriptBlock {
Get-ChildItem C:\Windows -File -Recurse -ErrorAction SilentlyContinue |
Measure-Object
}
Состояние задания:
Get-Job
Получить результат:
Receive-Job $job
Удалить ненужное задание:
Remove-Job $job
Start-Job удобен, но с самого начала тащить в задания всё подряд не нужно. Сначала выполняйте как обычно и выносите в задания только медленные операции — так проще ориентироваться.
30. История команд
Когда это нужно: когда команду собирали методом проб, она наконец заработала, и её нужно перенести в инструкцию или скрипт.
Чтобы посмотреть ранее выполненные команды, используют Get-History.
Get-History
Удобнее смотреть только строки команд:
Get-History |
Select-Object Id, CommandLine
Повторно выполнить конкретную запись истории:
Invoke-History 12
История удобна, но с её помощью можно повторно выполнить и опасные команды. Перед повторным запуском изменяющих команд вроде Remove-Item или Stop-Process из истории сначала проверьте их содержимое.
31. Посмотреть детали ошибки — Get-Error
В PowerShell 7 недавнюю ошибку подробно смотрят через Get-Error.
Get-Error
Только последнее сообщение об ошибке:
$Error[0].Exception.Message
Когда возникает ошибка, не ограничивайтесь красным текстом на экране — проверьте следующее:
На какой команде произошёл сбой
На каком пути или объекте произошёл сбой
Не проблема ли это с правами
Не отсутствует ли файл
Не проблема ли это сети или блокировки
Чтобы сохранить результаты разбора, сочетайте это с Start-Transcript и Export-Csv.
32. Часто используемые операторы сравнения
В Where-Object постоянно используют операторы сравнения.
| Оператор | Значение | Пример |
|---|---|---|
-eq |
Равно | $_.Status -eq "Running" |
-ne |
Не равно | $_.Status -ne "Running" |
-gt |
Больше | $_.Length -gt 10MB |
-ge |
Больше или равно | $_.Length -ge 10MB |
-lt |
Меньше | $_.Length -lt 10MB |
-le |
Меньше или равно | $_.Length -le 10MB |
-like |
Совпадение по маске | $_.Name -like "*.log" |
-match |
Совпадение по регулярному выражению | $_.Name -match "^app" |
-in |
Значение есть в списке | $_.Status -in @("Running", "Paused") |
-contains |
Список содержит значение | @("a", "b") -contains "a" |
Примеры.
Get-ChildItem . -File |
Where-Object { $_.Length -gt 10MB }
Get-Service |
Where-Object { $_.Status -in @("Running", "Paused") }
Get-ChildItem . -File |
Where-Object { $_.Name -match "\.log$" }
Поначалу вполне достаточно -eq, -ne, -gt, -lt и -like. Когда освоитесь, -match и -in позволяют записывать условия короче.
33. Небольшие рабочие рецепты
Дальше — примеры в форме, которую можно сразу использовать в работе.
Посмотреть число файлов по расширениям
Get-ChildItem C:\Work -File -Recurse |
Group-Object -Property Extension -NoElement |
Sort-Object -Property Count -Descending
Так примерно понимают, что лежит в папке.
Посмотреть 20 самых больших файлов
Get-ChildItem C:\Work -File -Recurse |
Sort-Object -Property Length -Descending |
Select-Object -First 20 FullName, @{Name="SizeMB"; Expression={ [math]::Round($_.Length / 1MB, 2) }}
Часто нужно при разборе места на диске.
Посмотреть файлы, изменённые за последние 24 часа
$since = (Get-Date).AddHours(-24)
Get-ChildItem C:\Work -File -Recurse |
Where-Object { $_.LastWriteTime -ge $since } |
Select-Object FullName, Length, LastWriteTime
После инцидента так смотрят, какие файлы успели измениться.
Собрать строки логов с ERROR в CSV
Select-String -Path C:\App\Logs\*.log -Pattern "ERROR" |
Select-Object Path, LineNumber, Line |
Export-Csv .\error-lines.csv -NoTypeInformation -Encoding UTF8
Так результаты разбора проще передавать дальше.
Посмотреть две строки до и после ERROR
Select-String -Path C:\App\Logs\*.log -Pattern "ERROR" -Context 2
Когда нужно увидеть, что происходило вокруг причины.
Посмотреть процессы с наибольшим использованием памяти
Get-Process |
Sort-Object -Property WorkingSet -Descending |
Select-Object -First 10 Name, Id, @{Name="MemoryMB"; Expression={ [math]::Round($_.WorkingSet / 1MB, 1) }}
Посмотреть службы с автозапуском, которые при этом остановлены
Get-Service |
Where-Object { $_.StartType -eq "Automatic" -and $_.Status -ne "Running" } |
Select-Object Name, DisplayName, Status, StartType
Собрать ошибки журнала System в CSV
Get-WinEvent -LogName System -MaxEvents 500 |
Where-Object { $_.LevelDisplayName -eq "Error" } |
Select-Object TimeCreated, ProviderName, Id, Message |
Export-Csv .\system-errors.csv -NoTypeInformation -Encoding UTF8
Отправить результат команды в буфер обмена
Get-Service |
Select-Object Name, DisplayName, Status |
ConvertTo-Csv -NoTypeInformation |
Set-Clipboard
Удобно, когда нужно вставить в письмо или чат.
Сравнить список файлов до и после работы
Get-ChildItem C:\Work -File |
Select-Object -ExpandProperty Name |
Set-Content .\before.txt -Encoding UTF8
После работы снимите список ещё раз.
Get-ChildItem C:\Work -File |
Select-Object -ExpandProperty Name |
Set-Content .\after.txt -Encoding UTF8
Сравним.
Compare-Object (Get-Content .\before.txt) (Get-Content .\after.txt)
Посмотреть суммарный размер папки в GB
$size = Get-ChildItem C:\Work -File -Recurse |
Measure-Object -Property Length -Sum
[math]::Round($size.Sum / 1GB, 2)
34. Оговорки при сочетании с изменяющими командами
Большая часть выше — команды чтения, и с ними можно экспериментировать сравнительно свободно. А вот эти команды — изменяющие.
| Операция | Команда |
|---|---|
| Копирование | Copy-Item |
| Перемещение | Move-Item |
| Удаление | Remove-Item |
| Переименование | Rename-Item |
| Остановка процесса | Stop-Process |
| Перезапуск службы | Restart-Service |
| Постоянная настройка переменной окружения | [Environment]::SetEnvironmentVariable() |
Изменяющие команды используют в таком порядке:
1. Посмотреть объекты командами Get-
2. Отфильтровать через Where-Object
3. Проверить список объектов через Select-Object
4. Посчитать через Measure-Object
5. При необходимости сохранить копию через Export-Csv
6. Если есть -WhatIf, сделать пробный прогон
7. Выполнить
Например, при удалении старых файлов .tmp.
Сначала посмотрим объекты.
$limit = (Get-Date).AddDays(-30)
$targets = Get-ChildItem C:\Temp -Filter *.tmp -File -Recurse |
Where-Object { $_.LastWriteTime -lt $limit }
$targets |
Select-Object FullName, Length, LastWriteTime
Посчитаем.
$targets | Measure-Object
Сохраним в CSV.
$targets |
Select-Object FullName, Length, LastWriteTime |
Export-Csv .\delete-targets.csv -NoTypeInformation -Encoding UTF8
Проверим, что именно будет удалено.
$targets | Remove-Item -WhatIf
Если всё в порядке, выполняйте.
$targets | Remove-Item
Один этот порядок сильно снижает число ошибок.
35. Как запоминать
Учить команды по отдельности тяжело, поэтому проще запоминать их по задаче.
| Задача | Команда, которую нужно вспомнить |
|---|---|
| Посчитать | Measure-Object |
| Просуммировать | Measure-Object -Sum |
| Посмотреть по типам | Group-Object |
| Убрать дубликаты | Sort-Object -Unique |
| Получить только значения | Select-Object -ExpandProperty |
| Собрать столбцы | Select-Object |
| Посмотреть по убыванию | Sort-Object -Descending |
| Найти строку | Select-String |
| Посмотреть соседний контекст | Select-String -Context |
| Сравнить два набора | Compare-Object |
| Сохранить копию | Export-Csv / Start-Transcript |
| Вывести и на экран, и в файл | Tee-Object |
| Отправить в буфер обмена | Set-Clipboard |
| Измерить время | Measure-Command |
| Посмотреть детали ошибки | Get-Error |
Шпаргалка на одну страницу
Сводная таблица с готовыми командами — её можно распечатать и держать под рукой. Большую часть повседневных задач собирают уже из неё.
| Задача | Готовая форма |
|---|---|
| Посчитать файлы | Get-ChildItem . -File \| Measure-Object |
| Суммарный размер в GB | [math]::Round((Get-ChildItem . -File -Recurse \| Measure-Object -Property Length -Sum).Sum / 1GB, 2) |
| Число файлов по расширениям | Get-ChildItem . -File \| Group-Object -Property Extension -NoElement \| Sort-Object -Property Count -Descending |
| 20 самых больших файлов | Get-ChildItem . -File -Recurse \| Sort-Object Length -Descending \| Select-Object -First 20 FullName, Length |
| Изменённые за последние 24 часа | Get-ChildItem . -File -Recurse \| Where-Object { $_.LastWriteTime -gt (Get-Date).AddDays(-1) } |
| Достать только значения | Get-Service \| Select-Object -ExpandProperty Name |
| Убрать дубликаты | Get-Content .\list.txt \| Sort-Object -Unique |
| Найти ERROR в логах | Select-String -Path .\logs\*.log -Pattern "ERROR" |
| Две строки до и после ERROR | Select-String -Path .\logs\*.log -Pattern "ERROR" -Context 2 |
| Сравнить два списка | Compare-Object -ReferenceObject (Get-Content .\before.txt) -DifferenceObject (Get-Content .\after.txt) |
| Проверить хеш | Get-FileHash .\installer.exe -Algorithm SHA256 |
| Результат в буфер обмена | Get-Service \| Select-Object Name, Status \| ConvertTo-Csv -NoTypeInformation \| Set-Clipboard |
| И на экран, и в файл | Get-Process \| Tee-Object -FilePath .\out.txt |
| Начать журнал работы | Start-Transcript -Path .\work.log |
| Отфильтровать CSV | Import-Csv .\data.csv \| Where-Object { $_.Status -eq "NG" } |
| Сохранить в CSV | ... \| Export-Csv .\out.csv -NoTypeInformation -Encoding UTF8 |
| Процессы с большой памятью | Get-Process \| Sort-Object WorkingSet -Descending \| Select-Object -First 10 Name, Id, WorkingSet |
| Остановленные службы с автозапуском | Get-Service \| Where-Object { $_.StartType -eq "Automatic" -and $_.Status -ne "Running" } |
| Ошибки журнала событий | Get-WinEvent -LogName System -MaxEvents 200 \| Where-Object { $_.LevelDisplayName -eq "Error" } |
| Проверить доступность | Test-NetConnection -ComputerName example.local -Port 443 |
| Измерить время выполнения | Measure-Command { ... } |
| Подробности последней ошибки | Get-Error |
Порядок, который нельзя пропускать
смотреть → считать → привести к виду → сохранить → пробный прогон → выполнить
Format-Table и Format-List ставят в самый конец этой цепочки — только когда смотрите на экран. Если вставить их перед Export-Csv или следующей командой, дальше конвейер ломается.
36. Итог
PowerShell по-настоящему силён, когда вы умеете писать скрипты. Но в повседневной работе чаще всего нужны как раз сочетания коротких команд.
Посчитать
Отсортировать
Сгруппировать
Сравнить
Найти
Извлечь
Сохранить
Отправить в буфер обмена
Сохранить журнал работы
Уже одно умение делать это заметно облегчает повседневную работу. Сложную автоматизацию с порога строить не нужно.
Сначала научитесь точно видеть ситуацию командами чтения, а изменяющие команды вроде Copy-Item, Move-Item, Remove-Item, Restart-Service подключайте только когда это действительно нужно.
Безопасный приём работы с PowerShell — вот этот порядок:
смотреть → считать → привести к виду → сохранить → пробный прогон → выполнить
Когда этот шаблон входит в привычку, PowerShell перестаёт быть «чёрным экраном, куда вбивают команды», и становится рабочим инструментом для ежедневного разбора, наведения порядка и отчётности.
Похожие статьи
Недавние статьи с теми же тегами помогут подробнее изучить близкие темы.
Основы команд PowerShell — операции, которые стоит выучить первыми, и как использовать их безопасно
Чтобы в реальной работе не теряться с PowerShell, разбираем поиск командлетов, конвейер, операции с файлами, обработку CSV, политику выпо...
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-ChildItem в Measure-Object. Число файлов смотрите в свойстве Count; чтобы захватить и вложенные папки, добавьте -Recurse. Суммарный размер считают так: Measure-Object -Property Length -Sum. В байтах читать неудобно, поэтому переведите в гигабайты, например [math]::Round($size.Sum / 1GB, 2). Если добавить -Average и -Maximum, среднее и максимум получатся за тот же проход.
- Чем Select-Object -ExpandProperty отличается от обычного указания свойства?
- Select-Object Name возвращает таблицу объектов со столбцом Name, а Select-Object -ExpandProperty Name возвращает сами значения Name, без обёртки. Если результат уходит в CSV, лучше оставить столбец. Если значения нужно передать другой команде, в строковую обработку или в текстовый файл — удобнее -ExpandProperty. Выбор зависит от того, что вы делаете дальше.
- Почему нельзя ставить Format-Table перед Export-Csv?
- Format-Table и Format-List — команды для экрана: они подменяют вывод объектами форматирования, и после этого CSV и дальнейшая обработка идут уже не по исходным данным. Для CSV сначала выберите столбцы через Select-Object и только потом передайте в Export-Csv. Запомнить просто: смотрите на экран — Format-*; результат ещё понадобится — Select-Object.
- Как безопасно пользоваться изменяющими командами вроде Remove-Item?
- Не запускайте сразу. Сначала посмотрите объекты командами Get-, сузьте выборку через Where-Object, проверьте список через Select-Object, посчитайте через Measure-Object и при необходимости сохраните копию через Export-Csv. Если у команды есть -WhatIf, сделайте пробный прогон и убедитесь, что удалится или переместится именно то, что нужно, — и только потом выполняйте. Один этот порядок сильно снижает число ошибок.
Об авторе
Страница с профилем автора статьи.
Го Комура
Представитель KomuraSoft LLC
Специализируется на разработке программного обеспечения для Windows, техническом консалтинге и расследовании сбоев, особенно в проектах с унаследованными системами и трудно воспроизводимыми ошибками.