Skip to content

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.json

6. Ошибки: поведение и 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 (расширенная) ​

BashPowerShell
cmd > f, >>`cmd
cmd 2>f, 2>&1cmd 2> f (потоки прямо: 2>&1 тоже есть)
cat, grepGet-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%MGet-Date -Format 'HHmm'
`sortuniq -c`

13. Три ошибки новичка в PowerShell ​

  1. Сравнение через = — это присваивание. Всегда -eq.
  2. Ждать текста там, где объект: Get-NetAdapter | Select Name — выбери свойства, а не пытайся парсить колонки как в bash.
  3. Игнорировать $LASTEXITCODE после внешних программ — командлеты не бросают исключений по умолчанию, а ssh.exe может упасть молча.

Связанные главы: Скрипты-оркестраторы (netlab.ps1, wt.exe), Диагностика Windows-клиента (ipconfig/netsh/Test-NetConnection), Bash для сетевика (та же логика на Linux).