Основы команд PowerShell — операции, которые стоит выучить первыми, и как использовать их безопасно
· Го Комура · PowerShell, Windows, Командная строка, Автоматизация, Использование существующих активов
1. Что нужно понять в первую очередь
PowerShell — это командная среда, которую можно использовать для проверки настроек Windows, упорядочивания файлов, анализа логов, обработки CSV, управления службами и автоматизации рутинных задач.
При этом с самого начала не нужно писать сложные скрипты. Если вы освоите только следующую последовательность, этого уже будет вполне достаточно для повседневной работы.
Искать → Смотреть → Фильтровать → Сортировать → Выводить → При необходимости изменять
Основа PowerShell — не «зазубривание длинных команд». Важны три вещи:
- Умение искать команды через
Get-CommandиGet-Help - Умение передавать результат следующей команде через конвейер
| - Проверка последствий через
-WhatIfи-Confirmперед удалением, остановкой или изменением
PowerShell позволяет выполнять «исследование» и «изменение» на одном и том же экране. Это удобно, но удаление или остановка выполняются так же мгновенно, поэтому важна привычка начинать с проверок, доступных только для чтения.
Код, который встречается в этой статье, опубликован на GitHub в виде полного набора примеров: коллекция скриптов по темам, соответствующим главам статьи (организована так, что можно безопасно тренироваться в рабочей области, создаваемой во временной папке), а также тесты Pester.
powershell-command-basics - komurasoft-blog-samples (GitHub)
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
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
Часто используемые сочетания приведены ниже.
| Команда | Роль | Пример |
|---|---|---|
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
Для фильтрации по расширению удобен -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
Просмотр последних 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
- Import-Csv - Microsoft Learn
- Export-Csv - Microsoft Learn
- about_Execution_Policies - Microsoft Learn
Похожие статьи
- Разбираемся с кодировками символов и переносами строк в Windows
- Руководство по миграции в связи с прекращением поддержки VBScript
- Подводные камни разработки COM/OCX/ActiveX
Услуги, связанные с этой темой
Разработка Windows-приложений
Мы поддерживаем разработку Windows-ПО: бизнес-приложения, интеграцию с оборудованием, коммуникационные инструменты.
Посмотреть услугу / Связаться с нами
Использование и миграция существующих активов
Мы поддерживаем инвентаризацию, доработку и миграцию существующих активов, включая старые batch-файлы, VBScript, VBA, PowerShell, COM / ActiveX.
Похожие статьи
Недавние статьи с теми же тегами помогут подробнее изучить близкие темы.
Практические команды PowerShell — расширяем набор маленьких инструментов для повседневной работы
Практическая подборка команд PowerShell для повседневной работы: разбираем, где применять Measure-Object, Group-Object, Select-String, Co...
Как запустить PowerShell из C# (CSharp) и получить результат в виде объектов
Разбираем, как запустить PowerShell из C# и получать результаты не строками, а объектами PSObject, — от PowerShell SDK, AddCommand и AddP...
Тестирование PowerShell с помощью Pester — практический подход к тому, чтобы эксплуатационные скрипты было труднее сломать
Практическое руководство по тестированию PowerShell-скриптов с помощью Pester v5: безопасное покрытие обработки дат, файловых операций, л...
Обработка ошибок и повторные попытки в PowerShell — от ловушки нерабочего try/catch до exit code и типовых схем повтора
Разбираем на практике различия между завершающими и незавершающими ошибками в PowerShell, ловушку неработающего try/catch и приём -ErrorA...
Политика выполнения PowerShell и подпись скриптов — практическое руководство, как перестать «затыкать дыры» параметром Bypass
Политика выполнения PowerShell — это «не граница безопасности, а защитный механизм». Разбираем различия между RemoteSigned и другими поли...
Связанные темы
Эти страницы показывают тему статьи в более широком контексте услуг и решений.
Технические темы 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, техническом консалтинге и расследовании сбоев, особенно в проектах с унаследованными системами и трудно воспроизводимыми ошибками.
Публичные ссылки