Внешний вид
PowerShell для сетевика: от первой команды до боевых скриптов
Зачем: на Windows-машинах клиентов и серверов PowerShell — главный инструмент автоматизации. По смыслу это тот же bash, только команды выдают не текст, а объекты, и это меняет всё. Если читал главу Bash для сетевика — здесь найдёшь всё то же, но «по-виндовому», плюс виндовая сетевая экзотика.
1. Философия: объекты вместо текста
Bash передаёт по пайпу строки — поэтому там grep/awk/sed. PowerShell передаёт объекты с полями — поэтому фильтруешь и форматируешь свойствами:
powershell
Get-NetAdapter # объекты-адаптеры
Get-NetAdapter | Where-Object Status -eq 'Up' # только поднятые (аналог grep)
Get-NetAdapter | Select-Object Name, LinkSpeed # только нужные поля (аналог awk '{print}')
Get-NetAdapter | Sort-Object Name | Format-Table -AutoSizeКоманды-«глаголы» всегда вида Verb-Noun (Get-Help, Test-Connection) — поэтому язык можно угадывать. Не знаешь команду:
powershell
Get-Command *adapter* # найти команду по куску имени
Get-Help Test-NetConnection -Examples # справка с примерами (читай!)
Update-Help # обновить справку (один раз)2. Переменные, типы, операторы
powershell
$gw = "192.168.1.1" # переменные с $
$ips = @("192.168.1.11","192.168.1.12") # массив
$name = Read-Host "Имя хоста" # ввод от пользователя
# сравнения: -eq -ne -gt -lt -like -match(регулярки!) -and -or -not
if ($pingOk -and ($dnsOk -eq $false)) { ... }
"192.168.1.1" -match '^\d{1,3}(\.\d{1,3}){3}$' # True — regex встроен
"я" -replace 'я', 'ты' # как sed 's/я/ты/'Важно: = — присваивание, -eq — сравнение (в bash наоборот: = сравнивает строки). $_ — «текущий объект в конвейере» (аналог $0/строки в awk).
3. Конвейер: Where / ForEach / Select / Sort
powershell
# из всех процессов — топ-5 по памяти, только имя и МБ
Get-Process | Sort-Object WorkingSet -Descending | Select-Object -First 5 Name, @{n='MB';e={[math]::Round($_.WorkingSet/1MB)}}
# для каждого — действие (аналог цикла + echo)
1..254 | ForEach-Object { "192.168.1.$_" }4. Условия и циклы
powershell
if (Test-Connection $gw -Count 1 -Quiet) { "шлюз жив" } else { "АЛАРМ" }
switch ($os) { "Windows" {"win"} "Linux" {"lin"} default {"?"} }
foreach ($ip in $ips) { ... }
while ($true) { ...; Start-Sleep 5 }
1..10 | ForEach-Object { $_ } # диапазон чисел5. Функции и параметры
powershell
function Test-Host {
param(
[Parameter(Mandatory=$true)][string]$Ip,
[int]$TimeoutSec = 2
)
$ok = Test-Connection -TargetName $Ip -Count 1 -Quiet -TimeoutSeconds $TimeoutSec
[pscustomobject]@{ Ip = $Ip; Alive = $ok; Time = (Get-Date -Format 'HH:mm') }
}
Test-Host -Ip 192.168.100.1 # вывод — объект, а не текст!Вывод функции — объект → его можно копить в массив и экспортировать в CSV/JSON — так делают отчёты:
powershell
$report = 1..20 | ForEach-Object { Test-Host "192.168.100.$_" }
$report | Format-Table # на экран
$report | Export-Csv report.csv -NoTypeInformation # в файл для начальства
$report | ConvertTo-Json | Out-File report.json6. Ошибки: поведение и try/catch
powershell
$ErrorActionPreference = 'Stop' # как set -e: любая ошибка стоп (в начале скрипта)
try {
Get-Content C:\nope.txt -ErrorAction Stop
} catch {
Write-Host "Ошибка: $($_.Exception.Message)" -ForegroundColor Red
} finally {
# cleanup: закрыть файл, удалить временное — всегда выполнится
}
$LASTEXITCODE # код возврата ВНЕШНЕЙ программы (ssh.exe, ping.exe)
if ($LASTEXITCODE -ne 0) { "ssh упал" }Правило: командлеты читают $ErrorActionPreference/-ErrorAction, а внешние exe — нет, смотри $LASTEXITCODE.
7. Файлы и перенаправления (аналог >, >>, tee)
powershell
"текст" | Out-File log.txt # записать (перезапись)
"ещё" | Add-Content log.txt # дописать (аналог >>)
Get-Content switches.txt | ForEach-Object { Test-Host $_ } # прочитать файл построчно
Get-Content log.txt | Select-String -Pattern "fail|error" # как grep
Copy-Item, Move-Item, Remove-Item, Test-Path, New-Item -ItemType Directory
"вывод на экран И в файл" | Tee-Object -FilePath out.log # как teeПути: Join-Path $env:USERPROFILE "report.txt" (безопасное склейивание), $PSScriptRoot — папка самого скрипта (аналог dirname $0).
8. Сетевой арсенал (виндовая специфика)
powershell
Test-Connection ya.ru -Count 2 # ping
Test-NetConnection ya.ru -Port 443 # ping + TCP-порт (TCP-test!)
Resolve-DnsName ya.ru # как nslookup/dig
Get-NetAdapter # адаптеры и статус
Get-NetIPAddress -AddressFamily IPv4 # адреса (аналог ip a)
Get-NetRoute -DestinationPrefix 0.0.0.0/0 # default route
Get-DnsClientServerAddress # какие DNS видит машина
arp -a # таблица соседей
netsh wlan show interfaces # Wi-Fi: сигнал/канал
netsh interface show interface # быстрый статус линков
New-NetIPAddress -InterfaceAlias "Ethernet" -IPAddress 192.168.100.11 -PrefixLength 24 -DefaultGateway 192.168.100.1 # статика
Set-NetIPInterface -InterfaceAlias "Ethernet" -Dhcp Enabled # обратно на DHCP
ipconfig /flushdns # сброс DNS-кэша (помнишь главу про Windows?)9. Удалённое выполнение по многим машинам
powershell
# по SSH (встроен в Win10+; ключи — как в Linux)
ssh admin@192.168.1.10 "ipconfig /all"
# сразу на список хостов (если настроен PowerShell Remoting / WinRM)
$hosts = "srv-01","srv-02","srv-03"
Invoke-Command -ComputerName $hosts -ScriptBlock { Get-Service dhcp* }10. Скрипт целиком: «утренний обход сети» (твой morning-check.ps1)
powershell
#Requires -Version 5.1
<#
.SYNOPSIS
Утренний обход: пингует хосты из списка, пишет отчёт CSV.
.EXAMPLE
.\morning-check.ps1 -ListFile hosts.txt
#>
param(
[string]$ListFile = "hosts.txt",
[string]$Report = "report-$(Get-Date -Format 'yyyyMMdd-HHmm').csv"
)
$ErrorActionPreference = 'Continue' # один мёртвый хост не роняет обход
$results = Get-Content $ListFile | Where-Object { $_ -match '\S' } | ForEach-Object {
$ip = $_.Trim()
$ok = Test-Connection -TargetName $ip -Count 2 -Quiet -TimeoutSeconds 2
[pscustomobject]@{ Host=$ip; Status=$(if ($ok) {'OK'} else {'DOWN'}); Checked=(Get-Date -Format 'HH:mm') }
}
$results | Format-Table -AutoSize
$results | Export-Csv $Report -NoTypeInformation -Encoding UTF8
Write-Host "Отчёт: $Report" -ForegroundColor GreenСравни с bash-версией из главы про bash: смысл один в один — while read ↔ Get-Content | ForEach-Object, &&/|| ↔ if/else, tee ↔ Export-Csv.
11. Запуск и политики безопасности
powershell
Get-ExecutionPolicy # что разрешено
Set-ExecutionPolicy -Scope CurrentUser RemoteSigned # свои скрипты можно, чужие — только подписанные
powershell -File .\morning-check.ps1 # запуск из cmd
.\morning-check.ps1 # из PowerShell (нужен .\ — как ./ в bash!)12. Шпаргалка bash ↔ PowerShell (расширенная)
| Bash | PowerShell |
|---|---|
cmd > f, >> | `cmd |
cmd 2>f, 2>&1 | cmd 2> f (потоки прямо: 2>&1 тоже есть) |
cat, grep | Get-Content, Select-String |
sed 's/a/b/' | -replace 'a','b' |
cut -d' ' -f1 | ` |
&&, ` | |
$?, $1, $# | $?, $args[0], $args.Count |
export VAR=x | $env:VAR = 'x' |
date +%H%M | Get-Date -Format 'HHmm' |
| `sort | uniq -c` |
13. Три ошибки новичка в PowerShell
- Сравнение через
=— это присваивание. Всегда-eq. - Ждать текста там, где объект:
Get-NetAdapter | Select Name— выбери свойства, а не пытайся парсить колонки как в bash. - Игнорировать
$LASTEXITCODEпосле внешних программ — командлеты не бросают исключений по умолчанию, а ssh.exe может упасть молча.
Связанные главы: Скрипты-оркестраторы (netlab.ps1, wt.exe), Диагностика Windows-клиента (ipconfig/netsh/Test-NetConnection), Bash для сетевика (та же логика на Linux).