
Если ты сетевой инженер или системный администратор, и PowerShell для тебя — это только Get-Help и Get-Process, то эта статья как раз для тебя. Я собрал десять командлетов, которые реально экономят время, нервы и, возможно, карьеру. Не все из них лежат на поверхности, но каждый стоит своего веса в золоте. Поехали!
1. Get-Command: «Что вообще ты умеешь, PowerShell?»
Когда забыл название команды, но помнишь, что она точно существует. Или хочешь понять, какие командлеты доступны в новом модуле.
# Простой поиск
Get-Command *service*
# Поиск по модулю (например, для NetTCPConnection)
Get-Command -Module NetTCPConnection
# Поиск по типу: cmdlet, function, alias
Get-Command -CommandType Cmdlet *net*
# Показать детали одной команды
Get-Command Get-Service | Format-List
💡 Почему это гениально:
Вместо гугления «как посмотреть службы в PowerShell» ты за 2 секунды находишь все команды со словом service. Особенно полезно при работе с новыми модулями типа Az или ExchangeOnline.
2. Select-Object: «Покажи мне только то, что нужно»
Многие думают, что это просто для выбора колонок. На самом деле — это швейцарский нож для работы с объектами.
# Базовое использование - выбор полей
Get-Process | Select-Object Name, CPU, WorkingSet
# Выбор первых/последних записей
Get-EventLog -LogName System -Newest 100 | Select-Object -First 10
Get-EventLog -LogName System -Newest 100 | Select-Object -Last 10
# Выбор уникальных значений
Get-Service | Select-Object Status -Unique
# Создание вычисляемых свойств (самая мощная фича!)
Get-Process | Select-Object Name,
@{Name="Memory(MB)";Expression={[math]::Round($_.WorkingSet/1MB,2)}},
@{Name="CPU_Time";Expression={$_.CPU.ToString("N2")}},
@{Name="Is_Heavy";Expression={$_.WorkingSet -gt 100MB}}
# Выбор по индексу (если объект - массив)
$services = Get-Service
$services[0..4] | Select-Object Name, Status
💡 Про-фишка:
Вычисляемые свойства — это суперсила. Можешь конвертировать байты в мегабайты, вычислять проценты, добавлять флаги — всё на лету, без промежуточных переменных.
3. Where-Object: «Отфильтруй это немедленно!»
Фильтрация — это 80% работы с данными. Where-Object делает это элегантно, особенно в PowerShell 7 с упрощённым синтаксисом.
# Классический синтаксис (PowerShell 5.1+)
Get-Service | Where-Object {$_.Status -eq "Running"}
# Упрощённый синтаксис (PowerShell 7+)
Get-Service | Where-Object Status -eq "Running"
# Несколько условий
Get-Process | Where-Object {
$_.CPU -gt 100 -and
$_.WorkingSet -gt 100MB -and
$_.Name -notlike "*chrome*"
}
# Фильтрация по шаблону
Get-Service | Where-Object Name -like "*sql*"
# Использование оператора -in
$importantServices = "WinRM", "Spooler", "EventLog"
Get-Service | Where-Object Name -in $importantServices
# Фильтрация по наличию свойства
Get-Process | Where-Object {$_.MainWindowTitle} | Select-Object Name, MainWindowTitle
⚡ Важно:
В PowerShell 7 появился «синтаксис без фигурных скобок» для простых условий. Меньше печатать — меньше ошибаться.
4. ForEach-Object: «Сделай это с каждым»
Циклы — хорошо, ForEach-Object — лучше. Особенно когда работаешь с конвейером.
# Базовый перебор
Get-Service | ForEach-Object {
Write-Host "Служба $($_.Name) имеет статус $($_.Status)" -ForegroundColor Cyan
}
# Возврат изменённых объектов
Get-ChildItem C:\Windows\*.log | ForEach-Object {
[PSCustomObject]@{
Name = $_.Name
Size_MB = [math]::Round($_.Length/1MB, 2)
LastAccess = $_.LastAccessTime.ToString("dd.MM.yyyy HH:mm")
IsOld = $_.LastAccessTime -lt (Get-Date).AddDays(-30)
}
}
# Параллельное выполнение! (PowerShell 7+)
1..10 | ForEach-Object -Parallel {
Start-Sleep -Seconds 1
"Элемент $_ обработан в потоке $([System.Threading.Thread]::CurrentThread.ManagedThreadId)"
} -ThrottleLimit 5
# Использование $PSItem (синоним $_)
Get-Process | ForEach-Object { $PSItem.Name }
🔥 Мега-фича:
ForEach-Object -Parallel в PowerShell 7 — это революция. Обрабатывай тысячи элементов, используя несколько ядер процессора. Прощай, однопоточность!
5. Group-Object: «Сгруппируй и властвуй»
Когда нужно понять закономерности: сколько служб запущено, какие процессы самые прожорливые, кто чаще всего пишет в лог.
# Группировка по статусу служб
Get-Service | Group-Object Status -NoElement |
Select-Object Count, Name |
Sort-Object Count -Descending
# Группировка с вычисляемым свойством
Get-Process | Group-Object {$_.Name.Substring(0,1).ToUpper()} |
Select-Object Name, Count,
@{Name="TotalMemory(MB)";Expression={[math]::Round(($_.Group.WorkingSet | Measure-Object -Sum).Sum/1MB,2)}} |
Sort-Object Count -Descending
# Группировка по нескольким свойствам
Get-EventLog -LogName System -EntryType Error -Newest 100 |
Group-Object Source, InstanceID |
Select-Object Count, Name |
Sort-Object Count -Descending |
Select-Object -First 5
# Сохранить группы для дальнейшего анализа
$groupedProcesses = Get-Process | Group-Object Company
$groupedProcesses | Where-Object Count -gt 5 | ForEach-Object {
Write-Host "Компания: $($_.Name) - процессов: $($_.Count)" -ForegroundColor Yellow
$_.Group | Select-Object -First 3 Name, CPU
}
📊 Аналитика:
Group-Object + Select-Object с вычисляемыми свойствами = мгновенная аналитика. За 30 секунд получаешь то, на что в GUI потратил бы 10 минут.
6. Sort-Object: «Всё по порядку»
Казалось бы, что тут сложного? Но и тут есть свои хитрости.
# Сортировка по одному полю
Get-Service | Sort-Object Status, Name | Format-Table -AutoSize
# Обратная сортировка
Get-Process | Sort-Object CPU -Descending | Select-Object -First 10 Name, CPU
# Сортировка по вычисляемому свойству
Get-ChildItem C:\Windows\*.exe |
Sort-Object @{Expression={$_.Length/1MB}; Descending=$true} |
Select-Object -First 10 Name,
@{Name="Size(MB)";Expression={[math]::Round($_.Length/1MB,2)}}
# Сортировка с учётом регистра
Get-ChildItem | Sort-Object Name -CaseSensitive
# Уникальность через сортировку (альтернатива Get-Unique)
Get-EventLog -LogName System -Newest 50 |
Select-Object -ExpandProperty Source |
Sort-Object -Unique
🎯 Секрет:
Sort-Object @{Expression={…}} позволяет сортировать по любым вычислениям. Хочешь отсортировать файлы по размеру в мегабайтах, а не в байтах? Легко!
7. Measure-Object: «Посчитай-ка это»
Статистика в одну строку. Больше не нужно писать циклы для подсчёта суммы или среднего.
# Базовые измерения
Get-Process | Measure-Object
# Сумма, среднее, минимум, максимум
Get-Process | Measure-Object WorkingSet -Sum -Average -Minimum -Maximum
# Сумма в человекочитаемом виде
$memoryStats = Get-Process | Measure-Object WorkingSet -Sum -Average
Write-Host "Всего памяти: $([math]::Round($memoryStats.Sum/1GB,2)) GB" -ForegroundColor Green
Write-Host "В среднем на процесс: $([math]::Round($memoryStats.Average/1MB,2)) MB" -ForegroundColor Cyan
# Подсчёт строк в файлах
Get-ChildItem *.ps1 -Recurse | ForEach-Object {
$lineCount = Get-Content $_.FullName | Measure-Object -Line
[PSCustomObject]@{
File = $_.Name
Lines = $lineCount.Lines
Path = $_.DirectoryName
}
} | Sort-Object Lines -Descending | Select-Object -First 10
# Подсчёт уникальных значений (альтернатива Group-Object)
Get-Service | Select-Object -ExpandProperty Status | Measure-Object
🧮 Магия чисел:
Measure-Object делает то, на что в других языках нужны отдельные функции или даже библиотеки. Всё встроено и оптимизировано.
8. Compare-Object: «Найди отличия»
Сравнение конфигураций, списков файлов, пользователей — ежедневная рутина. Compare-Object делает это безболезненно.
# Сравнение двух списков
$yesterday = Get-Service | Select-Object Name, Status
Start-Sleep -Seconds 60
$today = Get-Service | Select-Object Name, Status
Compare-Object $yesterday $today -Property Name, Status |
Where-Object SideIndicator -eq "=>" |
Select-Object Name, Status
# Сравнение файлов в папках
$sourceFiles = Get-ChildItem C:\Source -Recurse
$destFiles = Get-ChildItem C:\Backup -Recurse
Compare-Object $sourceFiles $destFiles -Property Name, Length, LastWriteTime |
Format-Table -AutoSize
# Сравнение с игнорированием регистра
$list1 = @("SERVER1", "server2", "Server3")
$list2 = @("server1", "SERVER2", "server4")
Compare-Object $list1 $list2 -CaseSensitive:$false
# Что есть в одном, но нет в другом
$domainUsers = Get-ADUser -Filter * | Select-Object -ExpandProperty SamAccountName
$localUsers = Get-LocalUser | Select-Object -ExpandProperty Name
$missingUsers = Compare-Object $domainUsers $localUsers |
Where-Object SideIndicator -eq "<=" |
Select-Object -ExpandProperty InputObject
🕵️♂️ Детектив:
Идеально для аудита. Что изменилось в конфигурации сервера? Какие пользователи появились/исчезли? Какие файлы не скопировались в бэкап?
9. Export-Csv / Import-Csv: «Экспорт во внешний мир»
PowerShell хорош, но иногда нужно поделиться результатами с Excel, Tableau или просто сохранить для истории.
# Экспорт в CSV
Get-Service |
Select-Object Name, Status, StartType, DisplayName |
Export-Csv -Path "C:\reports\services_$(Get-Date -Format 'yyyyMMdd').csv" -NoTypeInformation -Encoding UTF8
# Импорт CSV
$services = Import-Csv -Path "C:\reports\services_20231215.csv"
$services | Where-Object Status -eq "Stopped" | ForEach-Object {
Write-Host "Служба $($_.Name) остановлена" -ForegroundColor Red
}
# Работа с пользовательскими разделителями
Get-Process | Select-Object -First 5 Name, CPU |
Export-Csv -Path "processes.txt" -Delimiter "`t" -NoTypeInformation
# Экспорт с фильтрацией в одну строку
Get-EventLog -LogName System -EntryType Error -Newest 100 |
Select-Object TimeGenerated, Source, Message |
Export-Csv "system_errors.csv" -NoTypeInformation
# Импорт и преобразование типов
$data = Import-Csv "report.csv" | ForEach-Object {
[PSCustomObject]@{
Name = $_.Name
Date = [DateTime]$_.Date
Value = [int]$_.Value
}
}
📁 Совместимость:
CSV — универсальный формат. Импортируешь в Excel, загружаешь в базу данных, анализируешь в Python. Все довольны.
10. Get-Member: «Что внутри этого объекта?»
Самый важный командлет для изучения PowerShell. Не знаешь, что можно сделать с объектом? Спроси у Get-Member!
# Показать всё содержимое объекта
Get-Service | Get-Member
# Только свойства
Get-Process | Get-Member -MemberType Property
# Только методы
Get-Date | Get-Member -MemberType Method
# Поиск по имени
Get-ChildItem | Get-Member *time*
# Детальная информация о конкретном свойстве
(Get-Service)[0] | Get-Member -Name Status
# Практический пример: узнаём, какие методы есть у строки
"Hello, PowerShell" | Get-Member -MemberType Method |
Where-Object {$_.Name -like "*replace*"} |
Select-Object Name, Definition
# Узнаём, как преобразовать дату
Get-Date | Get-Member *string* | Select-Object Name, Definition
🎓 Учитель:
Get-Member — это документация, которая всегда с тобой. Не нужно лезть в интернет, чтобы понять, как работать с объектом. Все методы и свойства прямо перед тобой.
Бонус: Комбинируем всё вместе
Настоящая сила PowerShell — в комбинации командлетов. Вот реальный пример из жизни:
# Анализ логов: какие ошибки чаще всего встречаются за последний час?
Get-EventLog -LogName Application -After (Get-Date).AddHours(-1) -EntryType Error |
Group-Object Source |
Select-Object Name, Count,
@{Name="LastError";Expression={$_.Group[0].TimeGenerated}} |
Sort-Object Count -Descending |
Export-Csv "hourly_errors.csv" -NoTypeInformation
# Мониторинг диска: какие папки занимают больше всего места?
Get-ChildItem C:\ -Directory | ForEach-Object {
$size = Get-ChildItem $_.FullName -Recurse -File -ErrorAction SilentlyContinue |
Measure-Object -Property Length -Sum
[PSCustomObject]@{
Folder = $_.Name
Size_GB = [math]::Round($size.Sum / 1GB, 2)
Files = $size.Count
}
} | Sort-Object Size_GB -Descending |
Select-Object -First 10 |
Format-Table -AutoSize
# Сравнение конфигураций серверов
$server1 = Invoke-Command -ComputerName SRV01 {Get-Service | Select-Object Name, Status}
$server2 = Invoke-Command -ComputerName SRV02 {Get-Service | Select-Object Name, Status}
Compare-Object $server1 $server2 -Property Name, Status |
Where-Object SideIndicator -eq "=>" |
Group-Object SideIndicator |
ForEach-Object {
Write-Host "На сервере SRV0$($_.Name -replace '=',''):" -ForegroundColor Yellow
$_.Group | Select-Object -First 5 Name, Status
}
Золотое правило PowerShell: Если ты делаешь что-то вручную больше двух раз — автоматизируй это. Эти 10 командлетов — твой базовый набор. Комбинируй их, создавай конвейеры, пиши функции. Скоро ты обнаружишь, что 90% рутины можно упаковать в 10-20 строк кода.
Удачи в автоматизации! Помни: лень — двигатель прогресса, особенно если ты инженер.
📚 Что дальше?
Освоил эти командлеты? Пришло время для:
- Функций: Оберни свои конвейеры в функции с параметрами
- Модулей: Собери набор функций в модуль для повторного использования
- Pester: Напиши тесты для своих скриптов
- PowerShell 7: Переходи на новую версию для скорости и новых фич