⚡ Wiki-справочник · Windows PowerShell · Скрипты · Администрирование

PowerShell для системного администратора

Практический одностраничный сайт-справочник с командами, готовыми скриптами, пояснениями, типовыми сценариями для Windows, Windows Server, Active Directory, сети, служб, логов и автоматизации.

Перейти к готовым скриптам
18+готовых скриптов для администрирования
120+команд и практических примеров
15тематических wiki-разделов
UTF‑8корректная кодировка русского текста

Быстрый старт

PowerShell — это командная оболочка и язык автоматизации для Windows-администрирования. Главное отличие от классического CMD: PowerShell работает не только с текстом, а с объектами. Это позволяет фильтровать, сортировать, группировать и экспортировать данные намного удобнее.

Windows PowerShell 5.1

Встроен в Windows 10/11 и Windows Server. Часто используется для локального администрирования, GPO, AD, старых модулей.

PowerShell 7+

Современная кроссплатформенная версия. Подходит для новых скриптов, автоматизации, CI/CD, работы с REST API.

Windows Terminal

Удобная современная оболочка для вкладок PowerShell, CMD, WSL и SSH. Рекомендуется для повседневной работы.

Первые команды

КомандаЧто делаетПример
Get-CommandИщет доступные команды и cmdlet'ы.Get-Command *service*
Get-HelpПоказывает справку по команде.Get-Help Get-Process -Examples
Get-MemberПоказывает свойства и методы объекта.Get-Process | Get-Member
Where-ObjectФильтрует объекты по условию.Get-Service | ? Status -eq Running
Select-ObjectВыбирает нужные поля.Get-Process | Select Name, CPU
Sort-ObjectСортирует результат.Get-Process | Sort CPU -Descending
В PowerShell многие команды имеют псевдонимы: ls, dir, cd, cat, type. Но в скриптах лучше использовать полные имена: Get-ChildItem, Set-Location, Get-Content.

Синтаксис и конвейер

Конвейер | передаёт результат одной команды в другую. В CMD чаще передаётся текст, а в PowerShell — полноценные объекты с полями и методами.

Базовые конструкции

Переменные, условия, циклы
# Переменная
$ServerName = $env:COMPUTERNAME

# Условие
if ((Get-Service -Name Spooler).Status -eq 'Running') {
    Write-Host "Служба печати запущена"
} else {
    Write-Host "Служба печати остановлена"
}

# Цикл foreach
$Services = 'Spooler', 'W32Time', 'WinRM'
foreach ($Service in $Services) {
    Get-Service -Name $Service
}

# Конвейер
Get-Process |
    Where-Object CPU -gt 10 |
    Sort-Object CPU -Descending |
    Select-Object -First 10 Name, Id, CPU

Частые операторы сравнения

ОператорЗначениеПример
-eqравно$Status -eq 'Running'
-neне равно$Code -ne 0
-gtбольше$FreeGB -gt 20
-ltменьше$Days -lt 7
-likeпохоже по шаблону$Name -like '*SQL*'
-matchсовпадает с regex$Email -match '@company\.ru$'
-containsколлекция содержит значение$Roles -contains 'Admin'

Функция с параметрами

Пример функции
function Test-DiskFreeSpace {
    param(
        [string]$Drive = 'C:',
        [int]$MinFreeGB = 20
    )

    $Disk = Get-CimInstance Win32_LogicalDisk -Filter "DeviceID='$Drive'"
    $FreeGB = [math]::Round($Disk.FreeSpace / 1GB, 2)

    if ($FreeGB -lt $MinFreeGB) {
        Write-Warning "На диске $Drive мало места: $FreeGB GB"
    } else {
        Write-Host "На диске $Drive достаточно места: $FreeGB GB"
    }
}

Test-DiskFreeSpace -Drive 'C:' -MinFreeGB 15

Справка и исследование системы

Хороший администратор не запоминает все команды наизусть. Он быстро находит нужный cmdlet, читает примеры, смотрит параметры и понимает, какие объекты возвращает команда.

ЗадачаКомандаОписание
Найти командуGet-Command *user*Покажет команды, где в имени есть user.
Примеры использованияGet-Help Get-Service -ExamplesПокажет примеры по команде.
Полная справкаGet-Help Get-Process -FullПокажет описание, параметры, примеры.
Справка в браузереGet-Help Get-ChildItem -OnlineОткроет онлайн-документацию.
Свойства объектаGet-Service | Get-MemberПокажет поля и методы объектов службы.
Список модулейGet-Module -ListAvailableПокажет установленные модули.
Обновление локальной справки
# Запускать PowerShell от имени администратора
Update-Help -Force -ErrorAction SilentlyContinue

# Если справка не обновляется на сервере без интернета,
# можно использовать Save-Help на машине с интернетом и Update-Help -SourcePath.

Политика выполнения и безопасность

Политика выполнения не является полноценной системой безопасности, но помогает защититься от случайного запуска неподписанных или загруженных из интернета скриптов.

ПолитикаЧто означаетКогда использовать
RestrictedСкрипты не запускаются.Максимально консервативный режим.
RemoteSignedЛокальные скрипты запускаются, скачанные требуют подписи.Нормальный вариант для админской станции.
AllSignedВсе скрипты должны быть подписаны.Строгая корпоративная среда.
BypassОграничения отключены.Только точечно и осознанно.
Проверка и настройка Execution Policy
# Посмотреть политики по уровням
Get-ExecutionPolicy -List

# Разрешить локальные скрипты для текущего пользователя
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser

# Разовый запуск скрипта без изменения постоянной политики
powershell.exe -ExecutionPolicy Bypass -File .\script.ps1
Не запускайте чужие скрипты из интернета без просмотра кода. Особенно опасны команды с Invoke-Expression, скачиванием через Invoke-WebRequest, скрытым запуском PowerShell, изменением реестра, задач планировщика и автозагрузки.

Быстрая проверка подозрительного скрипта

Поиск опасных конструкций
$Path = '.\unknown-script.ps1'
$Patterns = 'Invoke-Expression','IEX','FromBase64String','EncodedCommand','New-Object Net.WebClient','Invoke-WebRequest','Start-Process','schtasks','Run\\','Startup'

foreach ($Pattern in $Patterns) {
    Select-String -Path $Path -Pattern $Pattern -SimpleMatch
}

Файлы и папки

PowerShell удобен для массовой работы с файлами: поиск старых логов, очистка временных папок, копирование, сравнение, проверка хэшей и настройка прав доступа.

ЗадачаКомандаКомментарий
Список файловGet-ChildItem C:\TempАналог dir/ls.
Рекурсивный поискGet-ChildItem C:\Logs -Recurse -Filter *.logИщет все log-файлы.
Файлы старше 30 днейGet-ChildItem C:\Logs -Recurse | ? LastWriteTime -lt (Get-Date).AddDays(-30)Полезно для очистки.
УдалениеRemove-Item C:\Temp\* -Recurse -ForceОсторожно: удаляет без корзины.
КопированиеCopy-Item C:\Data D:\Backup -RecurseКопирует папку с содержимым.
Хэш файлаGet-FileHash .\file.iso -Algorithm SHA256Проверка целостности.
Права доступаGet-Acl C:\ShareПоказывает ACL.

Поиск крупных файлов

Топ крупных файлов на диске
Get-ChildItem C:\ -Recurse -File -ErrorAction SilentlyContinue |
    Sort-Object Length -Descending |
    Select-Object -First 30 FullName, @{Name='SizeGB';Expression={[math]::Round($_.Length / 1GB, 2)}}

Очистка логов старше 60 дней

Безопасная очистка с WhatIf
$Path = 'C:\Logs'
$Days = 60

Get-ChildItem $Path -Recurse -File -Filter *.log -ErrorAction SilentlyContinue |
    Where-Object LastWriteTime -lt (Get-Date).AddDays(-$Days) |
    Remove-Item -Force -WhatIf

# После проверки уберите -WhatIf, чтобы реально удалить файлы.

Процессы и службы

Для ежедневного администрирования часто нужно найти зависший процесс, проверить службу, перезапустить сервис, изменить тип запуска или собрать статистику потребления ресурсов.

КомандаОписаниеПример
Get-ProcessПоказывает процессы.Get-Process | Sort CPU -Desc
Stop-ProcessЗавершает процесс.Stop-Process -Name notepad -Force
Get-ServiceПоказывает службы.Get-Service | ? Status -eq Stopped
Restart-ServiceПерезапускает службу.Restart-Service Spooler
Set-ServiceМеняет тип запуска.Set-Service Spooler -StartupType Automatic
Get-CounterСчитывает счётчики производительности.Get-Counter '\Processor(_Total)\% Processor Time'
Топ процессов по CPU и памяти
Get-Process |
    Select-Object Name, Id, CPU, @{Name='MemoryMB';Expression={[math]::Round($_.WorkingSet64 / 1MB, 1)}} |
    Sort-Object MemoryMB -Descending |
    Select-Object -First 20

Сеть и диагностика

PowerShell заменяет множество отдельных утилит: ping, nslookup, ipconfig, route, netstat. Для быстрой диагностики особенно полезны Test-NetConnection, Resolve-DnsName, Get-NetIPConfiguration и Get-NetTCPConnection.

ЗадачаКомандаЧто проверить
Проверить портTest-NetConnection server01 -Port 443Доступность сервиса.
DNS-запросResolve-DnsName ya.ruПравильно ли резолвится имя.
IP-конфигурацияGet-NetIPConfigurationIP, шлюз, DNS.
Активные TCPGet-NetTCPConnectionСетевые подключения.
МаршрутыGet-NetRouteТаблица маршрутизации.
Firewall rulesGet-NetFirewallRuleПравила брандмауэра.
Проверка списка портов
$Target = 'server01.company.local'
$Ports = 53, 80, 443, 445, 3389, 5985

foreach ($Port in $Ports) {
    $Result = Test-NetConnection -ComputerName $Target -Port $Port -WarningAction SilentlyContinue
    [PSCustomObject]@{
        Target = $Target
        Port = $Port
        Open = $Result.TcpTestSucceeded
    }
}
Список процессов, слушающих порты
Get-NetTCPConnection -State Listen |
    Select-Object LocalAddress, LocalPort, OwningProcess,
        @{Name='ProcessName';Expression={(Get-Process -Id $_.OwningProcess -ErrorAction SilentlyContinue).ProcessName}} |
    Sort-Object LocalPort

Журналы событий

Журналы Windows — один из главных источников диагностики. Через PowerShell можно быстро находить ошибки, неудачные входы, перезагрузки, падения служб и проблемы приложений.

ЗадачаКомандаКомментарий
Последние ошибки SystemGet-WinEvent -LogName System -MaxEvents 50Быстрый просмотр.
Только ошибкиGet-WinEvent -FilterHashtable @{LogName='System'; Level=2}Level 2 = Error.
События за суткиGet-WinEvent -FilterHashtable @{LogName='Application'; StartTime=(Get-Date).AddDays(-1)}Фильтр по времени.
Неудачные входыGet-WinEvent -FilterHashtable @{LogName='Security'; Id=4625}Нужны права администратора.
Успешные входыGet-WinEvent -FilterHashtable @{LogName='Security'; Id=4624}Может быть много событий.
Топ системных ошибок за последние 24 часа
Get-WinEvent -FilterHashtable @{
    LogName = 'System'
    Level = 2
    StartTime = (Get-Date).AddDays(-1)
} |
Group-Object ProviderName, Id |
Sort-Object Count -Descending |
Select-Object -First 15 Count, Name

Реестр

Реестр в PowerShell доступен как файловая система: HKLM: и HKCU:. Это удобно для проверки автозагрузки, политик, настроек приложений и системных параметров.

Перед массовым изменением реестра делайте экспорт ветки и используйте -WhatIf, если команда его поддерживает. Ошибка в реестре может привести к неработоспособности приложения или Windows.
ЗадачаКоманда
Прочитать значениеGet-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion'
Создать ключNew-Item 'HKCU:\Software\MyCompany' -Force
Создать параметрNew-ItemProperty -Path 'HKCU:\Software\MyCompany' -Name Enabled -Value 1 -PropertyType DWord
Изменить параметрSet-ItemProperty -Path 'HKCU:\Software\MyCompany' -Name Enabled -Value 0
Удалить параметрRemove-ItemProperty -Path 'HKCU:\Software\MyCompany' -Name Enabled
Проверка автозагрузки пользователя
Get-ItemProperty 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Run' |
    Select-Object * -ExcludeProperty PSPath, PSParentPath, PSChildName, PSDrive, PSProvider

Пользователи и группы

На рабочих станциях и серверах без домена PowerShell позволяет управлять локальными пользователями, группами, членством и базовым аудитом учётных записей.

КомандаНазначение
Get-LocalUserСписок локальных пользователей.
Get-LocalGroupСписок локальных групп.
Get-LocalGroupMember AdministratorsЧлены локальной группы администраторов.
New-LocalUserСоздать локального пользователя.
Add-LocalGroupMemberДобавить пользователя в группу.
Disable-LocalUserОтключить пользователя.
Создание локального пользователя
$Password = Read-Host "Введите пароль" -AsSecureString

New-LocalUser -Name 'support.user' `
    -Password $Password `
    -FullName 'Support User' `
    -Description 'Локальная учетная запись для поддержки'

Add-LocalGroupMember -Group 'Remote Desktop Users' -Member 'support.user'

Планировщик задач

Через PowerShell можно создавать задачи для регулярного запуска скриптов: очистка логов, резервное копирование, проверка служб, формирование отчётов.

КомандаЧто делает
Get-ScheduledTaskПоказывает задачи планировщика.
Get-ScheduledTaskInfoПоказывает статус, последний запуск, результат.
Start-ScheduledTaskЗапускает задачу вручную.
Disable-ScheduledTaskОтключает задачу.
Register-ScheduledTaskСоздаёт новую задачу.
Создание ежедневной задачи
$Action = New-ScheduledTaskAction -Execute 'powershell.exe' -Argument '-NoProfile -ExecutionPolicy Bypass -File C:\Scripts\DailyReport.ps1'
$Trigger = New-ScheduledTaskTrigger -Daily -At 9:00
$Principal = New-ScheduledTaskPrincipal -UserId 'SYSTEM' -RunLevel Highest

Register-ScheduledTask -TaskName 'Daily PowerShell Report' `
    -Action $Action `
    -Trigger $Trigger `
    -Principal $Principal `
    -Description 'Ежедневный административный отчет'

PowerShell Remoting

PowerShell Remoting позволяет выполнять команды на удалённых компьютерах через WinRM. Это один из ключевых инструментов для централизованного администрирования Windows Server.

Включение Remoting на сервере
# Запускать от имени администратора
Enable-PSRemoting -Force

# Проверить доступность WinRM
Test-WSMan server01

# Интерактивная сессия
Enter-PSSession -ComputerName server01

# Выполнить команду удаленно
Invoke-Command -ComputerName server01 -ScriptBlock {
    Get-Service | Where-Object Status -eq 'Stopped'
}

Выполнение команды на группе серверов

Массовая проверка серверов
$Servers = 'srv-file-01', 'srv-app-01', 'srv-sql-01'

Invoke-Command -ComputerName $Servers -ScriptBlock {
    [PSCustomObject]@{
        ComputerName = $env:COMPUTERNAME
        UptimeDays = [math]::Round(((Get-Date) - (Get-CimInstance Win32_OperatingSystem).LastBootUpTime).TotalDays, 1)
        FreeCGB = [math]::Round((Get-CimInstance Win32_LogicalDisk -Filter "DeviceID='C:'").FreeSpace / 1GB, 1)
    }
}
В доменной среде Remoting обычно работает проще. В workgroup-сценариях потребуется настроить TrustedHosts, HTTPS listener или корректную схему аутентификации. Не открывайте WinRM наружу в интернет.

CSV, JSON, XML и HTML

PowerShell силён в подготовке отчётов. Он умеет импортировать и экспортировать CSV, JSON, XML, а также быстро формировать HTML-таблицы для отправки по почте или публикации на внутреннем портале.

ФорматИмпортЭкспорт
CSVImport-Csv .\users.csvExport-Csv .\report.csv -NoTypeInformation -Encoding UTF8
JSONGet-Content .\data.json | ConvertFrom-Json$obj | ConvertTo-Json -Depth 5
XML[xml](Get-Content .\config.xml)$xml.Save('config.xml')
HTMLConvertFrom-HtmlConvertTo-Html
Экспорт отчета по службам в HTML
$ReportPath = 'C:\Temp\services-report.html'

Get-Service |
    Sort-Object Status, Name |
    Select-Object Name, DisplayName, Status, StartType |
    ConvertTo-Html -Title 'Service Report' -PreContent '

Service Report

' | Out-File $ReportPath -Encoding UTF8 Invoke-Item $ReportPath

Windows Server: ежедневное администрирование

Ниже — базовый набор команд для первичной диагностики сервера: версия ОС, аптайм, диски, сетевые настройки, роли, обновления, перезагрузка и pending reboot.

Информация о системе
System info
Get-ComputerInfo | Select-Object CsName, WindowsProductName, WindowsVersion, OsHardwareAbstractionLayer
Get-CimInstance Win32_OperatingSystem | Select-Object Caption, Version, LastBootUpTime
Диски и свободное место
Disks
Get-CimInstance Win32_LogicalDisk -Filter "DriveType=3" |
Select-Object DeviceID, VolumeName,
@{Name='SizeGB';Expression={[math]::Round($_.Size/1GB,1)}},
@{Name='FreeGB';Expression={[math]::Round($_.FreeSpace/1GB,1)}} 

Проверка необходимости перезагрузки

Pending reboot check
$Paths = @(
 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootPending',
 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired',
 'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager'
)

[PSCustomObject]@{
    ComputerName = $env:COMPUTERNAME
    CBSRebootPending = Test-Path $Paths[0]
    WindowsUpdateRebootRequired = Test-Path $Paths[1]
    PendingFileRenameOperations = [bool](Get-ItemProperty -Path $Paths[2] -Name PendingFileRenameOperations -ErrorAction SilentlyContinue)
}

Роли и компоненты Windows Server

Windows Features
# Только Windows Server
Get-WindowsFeature | Where-Object Installed -eq $true

# Установка роли, пример: Web Server IIS
Install-WindowsFeature -Name Web-Server -IncludeManagementTools

Hyper‑V

PowerShell хорошо подходит для автоматизации Hyper‑V: создание виртуальных машин, управление состоянием, чекпоинты, экспорт, подключение ISO и проверка ресурсов.

КомандаНазначение
Get-VMСписок виртуальных машин.
Start-VM VM01Запуск виртуальной машины.
Stop-VM VM01Остановка виртуальной машины.
Checkpoint-VM VM01Создание контрольной точки.
Export-VM VM01 -Path D:\ExportЭкспорт ВМ.
Get-VMSwitchСписок виртуальных коммутаторов.
Отчет по виртуальным машинам
Get-VM |
    Select-Object Name, State, ProcessorCount,
        @{Name='MemoryGB';Expression={[math]::Round($_.MemoryAssigned / 1GB, 1)}},
        Uptime,
        Status

IIS

Для управления IIS используется модуль WebAdministration. Через него можно смотреть сайты, пулы приложений, биндинги, перезапускать AppPool и автоматизировать базовое обслуживание веб-сервера.

Основные команды IIS
Import-Module WebAdministration

# Список сайтов
Get-Website

# Список пулов приложений
Get-ChildItem IIS:\AppPools

# Перезапуск пула
Restart-WebAppPool -Name 'DefaultAppPool'

# Статус сайта
Get-Website -Name 'Default Web Site' | Select-Object Name, State, PhysicalPath, Bindings

Готовые скрипты

Ниже — набор практических скриптов для повседневной работы. Перед использованием в боевой среде проверьте пути, права доступа, имена серверов и запустите сначала в тестовом режиме.

1. Комплексный отчёт о компьютере

Собирает имя ПК, ОС, аптайм, процессор, память, диски и IP-адреса. Подходит для первичной инвентаризации.

ИнвентаризацияWindowsОтчёт
Get-ComputerInventory.ps1
$OS = Get-CimInstance Win32_OperatingSystem
$CPU = Get-CimInstance Win32_Processor | Select-Object -First 1
$RAM = [math]::Round($OS.TotalVisibleMemorySize / 1MB, 2)
$Disks = Get-CimInstance Win32_LogicalDisk -Filter "DriveType=3" |
    Select-Object DeviceID, VolumeName,
        @{Name='SizeGB';Expression={[math]::Round($_.Size / 1GB, 2)}},
        @{Name='FreeGB';Expression={[math]::Round($_.FreeSpace / 1GB, 2)}}

$IPs = Get-NetIPAddress -AddressFamily IPv4 |
    Where-Object {$_.IPAddress -notlike '169.254*' -and $_.IPAddress -ne '127.0.0.1'} |
    Select-Object InterfaceAlias, IPAddress, PrefixLength

[PSCustomObject]@{
    ComputerName = $env:COMPUTERNAME
    OS = $OS.Caption
    Version = $OS.Version
    LastBoot = $OS.LastBootUpTime
    UptimeDays = [math]::Round(((Get-Date) - $OS.LastBootUpTime).TotalDays, 1)
    CPU = $CPU.Name
    RAMGB = $RAM
}

$Disks
$IPs

2. Health Check сервера

Проверяет свободное место на дисках, аптайм, критические службы, системные ошибки и pending reboot.

МониторингServerДиагностика
Server-HealthCheck.ps1
$CriticalServices = 'WinRM', 'W32Time', 'EventLog', 'LanmanServer'
$MinFreeGB = 15

$OS = Get-CimInstance Win32_OperatingSystem
$Disks = Get-CimInstance Win32_LogicalDisk -Filter "DriveType=3" | ForEach-Object {
    [PSCustomObject]@{
        Drive = $_.DeviceID
        FreeGB = [math]::Round($_.FreeSpace / 1GB, 2)
        SizeGB = [math]::Round($_.Size / 1GB, 2)
        Status = if (($_.FreeSpace / 1GB) -lt $MinFreeGB) { 'LOW' } else { 'OK' }
    }
}

$Services = foreach ($ServiceName in $CriticalServices) {
    $S = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
    [PSCustomObject]@{
        Service = $ServiceName
        Status = if ($S) { $S.Status } else { 'NotFound' }
    }
}

$Errors24h = Get-WinEvent -FilterHashtable @{
    LogName='System'; Level=2; StartTime=(Get-Date).AddDays(-1)
} -ErrorAction SilentlyContinue | Measure-Object

$PendingReboot = (Test-Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired')

[PSCustomObject]@{
    ComputerName = $env:COMPUTERNAME
    UptimeDays = [math]::Round(((Get-Date) - $OS.LastBootUpTime).TotalDays, 1)
    SystemErrors24h = $Errors24h.Count
    PendingReboot = $PendingReboot
}

$Disks
$Services

3. Очистка временных файлов

Удаляет старые файлы из временных папок пользователя и Windows. Сначала запускайте с -WhatIf.

ОчисткаДискиПоддержка
Clear-TempFiles.ps1
$Paths = @($env:TEMP, 'C:\Windows\Temp')
$Days = 7

foreach ($Path in $Paths) {
    if (Test-Path $Path) {
        Get-ChildItem $Path -Recurse -Force -ErrorAction SilentlyContinue |
            Where-Object { $_.LastWriteTime -lt (Get-Date).AddDays(-$Days) } |
            Remove-Item -Recurse -Force -ErrorAction SilentlyContinue -WhatIf
    }
}

# После проверки уберите -WhatIf.

4. Поиск крупных файлов

Находит самые крупные файлы на диске и экспортирует результат в CSV.

ДискиАнализCSV
Find-LargeFiles.ps1
$Root = 'C:\'
$Output = 'C:\Temp\large-files.csv'
$MinSizeMB = 500

Get-ChildItem $Root -Recurse -File -ErrorAction SilentlyContinue |
    Where-Object { $_.Length -gt ($MinSizeMB * 1MB) } |
    Select-Object FullName, LastWriteTime, @{Name='SizeMB';Expression={[math]::Round($_.Length / 1MB, 2)}} |
    Sort-Object SizeMB -Descending |
    Export-Csv $Output -NoTypeInformation -Encoding UTF8

Write-Host "Отчет сохранен: $Output"

5. Проверка сетевых портов

Проверяет список портов на сервере и показывает, какие доступны.

СетьПортыДиагностика
Test-Ports.ps1
$Target = 'server01.company.local'
$Ports = 80, 443, 445, 3389, 5985

$Results = foreach ($Port in $Ports) {
    $Test = Test-NetConnection -ComputerName $Target -Port $Port -WarningAction SilentlyContinue
    [PSCustomObject]@{
        Target = $Target
        Port = $Port
        TcpOpen = $Test.TcpTestSucceeded
        RemoteAddress = $Test.RemoteAddress
    }
}

$Results | Format-Table -AutoSize

6. Мониторинг и автоперезапуск службы

Проверяет службу и запускает её, если она остановлена. Можно повесить на планировщик задач.

СлужбыАвтоматизацияМониторинг
Watch-Service.ps1
$ServiceName = 'Spooler'
$LogPath = 'C:\Temp\service-watch.log'

$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue

if (-not $Service) {
    "$(Get-Date) Service $ServiceName not found" | Out-File $LogPath -Append -Encoding UTF8
    exit 1
}

if ($Service.Status -ne 'Running') {
    Start-Service -Name $ServiceName
    "$(Get-Date) Service $ServiceName was stopped and has been started" | Out-File $LogPath -Append -Encoding UTF8
} else {
    "$(Get-Date) Service $ServiceName is running" | Out-File $LogPath -Append -Encoding UTF8
}

7. Экспорт установленного ПО

Собирает список установленного программного обеспечения из реестра. Полезно для инвентаризации.

ИнвентаризацияПОRegistry
Export-InstalledSoftware.ps1
$Paths = @(
 'HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*',
 'HKLM:\Software\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*'
)

Get-ItemProperty $Paths -ErrorAction SilentlyContinue |
    Where-Object DisplayName |
    Select-Object DisplayName, DisplayVersion, Publisher, InstallDate |
    Sort-Object DisplayName |
    Export-Csv 'C:\Temp\installed-software.csv' -NoTypeInformation -Encoding UTF8

8. Проверка неудачных входов

Ищет события 4625 в Security log и группирует их по имени пользователя и IP-адресу.

БезопасностьАудитEvent Log
Get-FailedLogons.ps1
$Events = Get-WinEvent -FilterHashtable @{
    LogName = 'Security'
    Id = 4625
    StartTime = (Get-Date).AddDays(-1)
} -ErrorAction SilentlyContinue

$Results = foreach ($Event in $Events) {
    $Xml = [xml]$Event.ToXml()
    $Data = @{}
    foreach ($Node in $Xml.Event.EventData.Data) {
        $Data[$Node.Name] = $Node.'#text'
    }

    [PSCustomObject]@{
        TimeCreated = $Event.TimeCreated
        Account = $Data['TargetUserName']
        Workstation = $Data['WorkstationName']
        IpAddress = $Data['IpAddress']
        FailureReason = $Data['FailureReason']
    }
}

$Results |
    Group-Object Account, IpAddress |
    Sort-Object Count -Descending |
    Select-Object Count, Name

9. Резервное копирование папки через Robocopy

Использует надёжный robocopy, но запускается и логируется из PowerShell.

BackupRobocopyФайлы
Backup-Folder.ps1
$Source = 'D:\Data'
$Destination = '\\backup-server\backup\Data'
$Log = 'C:\Temp\robocopy-backup.log'

$Args = @(
    $Source,
    $Destination,
    '/MIR',
    '/R:2',
    '/W:5',
    '/Z',
    '/FFT',
    "/LOG:$Log",
    '/TEE'
)

Start-Process -FilePath 'robocopy.exe' -ArgumentList $Args -Wait -NoNewWindow
Write-Host "Backup finished. Log: $Log"
Ключ /MIR зеркалирует папку и может удалить файлы в назначении, если их нет в источнике.

10. Проверка срока действия сертификатов

Находит сертификаты, которые истекают в ближайшие 30 дней.

СертификатыБезопасностьМониторинг
Check-Certificates.ps1
$Days = 30

Get-ChildItem Cert:\LocalMachine\My |
    Where-Object { $_.NotAfter -lt (Get-Date).AddDays($Days) } |
    Select-Object Subject, Issuer, NotAfter, Thumbprint |
    Sort-Object NotAfter

11. Генерация HTML-отчёта по серверу

Формирует простой HTML-отчёт по дискам и службам. Можно отправлять по почте или хранить в архиве.

HTMLОтчётServer
New-ServerHtmlReport.ps1
$Path = 'C:\Temp\server-report.html'

$Disks = Get-CimInstance Win32_LogicalDisk -Filter "DriveType=3" |
    Select-Object DeviceID,
        @{Name='SizeGB';Expression={[math]::Round($_.Size/1GB,1)}},
        @{Name='FreeGB';Expression={[math]::Round($_.FreeSpace/1GB,1)}} |
    ConvertTo-Html -Fragment -PreContent '

Disks

' $Services = Get-Service | Where-Object Status -ne 'Running' | Select-Object Name, DisplayName, Status | ConvertTo-Html -Fragment -PreContent '

Stopped Services

' $Html = @" Server Report

Server Report: $env:COMPUTERNAME

Generated: $(Get-Date)

$Disks $Services "@ $Html | Out-File $Path -Encoding UTF8 Invoke-Item $Path

12. Массовая проверка свободного места на серверах

Через Remoting собирает свободное место на диске C: с нескольких серверов.

RemotingДискиМассовая проверка
Check-ServersDiskSpace.ps1
$Servers = Get-Content 'C:\Temp\servers.txt'

Invoke-Command -ComputerName $Servers -ScriptBlock {
    $Disk = Get-CimInstance Win32_LogicalDisk -Filter "DeviceID='C:'"
    [PSCustomObject]@{
        ComputerName = $env:COMPUTERNAME
        Drive = $Disk.DeviceID
        SizeGB = [math]::Round($Disk.Size / 1GB, 1)
        FreeGB = [math]::Round($Disk.FreeSpace / 1GB, 1)
        FreePercent = [math]::Round(($Disk.FreeSpace / $Disk.Size) * 100, 1)
    }
} | Export-Csv 'C:\Temp\servers-disk-space.csv' -NoTypeInformation -Encoding UTF8

13. Экспорт членов группы Active Directory

Выгружает членов AD-группы в CSV. Удобно для аудита доступов.

ADГруппыАудит
Export-ADGroupMembers.ps1
Import-Module ActiveDirectory

$GroupName = 'Domain Admins'
$Output = 'C:\Temp\domain-admins.csv'

Get-ADGroupMember -Identity $GroupName -Recursive |
    Where-Object objectClass -eq 'user' |
    Get-ADUser -Properties Department, Title, Mail, Enabled |
    Select-Object Name, SamAccountName, Enabled, Department, Title, Mail |
    Export-Csv $Output -NoTypeInformation -Encoding UTF8

14. Поиск заблокированных пользователей AD

Показывает заблокированные учётные записи и позволяет быстро их разблокировать после проверки причины.

ADHelpdeskУчетные записи
Find-LockedADUsers.ps1
Import-Module ActiveDirectory

Search-ADAccount -LockedOut -UsersOnly |
    Select-Object Name, SamAccountName, DistinguishedName

# Разблокировка конкретного пользователя:
# Unlock-ADAccount -Identity ivanov

15. Создание checkpoint для всех запущенных VM

Создаёт контрольные точки Hyper‑V для всех запущенных виртуальных машин перед обслуживанием.

Hyper‑VVMMaintenance
Checkpoint-RunningVMs.ps1
$CheckpointName = "Before maintenance $(Get-Date -Format 'yyyy-MM-dd HH-mm')"

Get-VM | Where-Object State -eq 'Running' | ForEach-Object {
    Checkpoint-VM -Name $_.Name -SnapshotName $CheckpointName
    Write-Host "Checkpoint created for $($_.Name)"
}

16. Перезапуск IIS AppPool при падении

Проверяет состояние пула приложений IIS и запускает его, если он остановлен.

IISWebAppPool
Watch-IISAppPool.ps1
Import-Module WebAdministration

$AppPool = 'DefaultAppPool'
$State = (Get-WebAppPoolState -Name $AppPool).Value

if ($State -ne 'Started') {
    Start-WebAppPool -Name $AppPool
    Write-Host "AppPool $AppPool был $State и теперь запущен"
} else {
    Write-Host "AppPool $AppPool работает нормально"
}

17. Поиск подозрительной автозагрузки

Проверяет популярные места автозагрузки: Run в HKCU/HKLM и папку Startup.

БезопасностьАвтозагрузкаIR
Check-AutorunsBasic.ps1
$RunKeys = @(
 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Run',
 'HKLM:\Software\Microsoft\Windows\CurrentVersion\Run',
 'HKLM:\Software\WOW6432Node\Microsoft\Windows\CurrentVersion\Run'
)

foreach ($Key in $RunKeys) {
    if (Test-Path $Key) {
        Write-Host "=== $Key ==="
        Get-ItemProperty $Key |
            Select-Object * -ExcludeProperty PSPath, PSParentPath, PSChildName, PSDrive, PSProvider
    }
}

Write-Host "=== Startup folders ==="
$StartupFolders = @(
    "$env:APPDATA\Microsoft\Windows\Start Menu\Programs\Startup",
    "$env:ProgramData\Microsoft\Windows\Start Menu\Programs\Startup"
)

foreach ($Folder in $StartupFolders) {
    if (Test-Path $Folder) {
        Get-ChildItem $Folder -Force
    }
}

18. Простая проверка целостности важных файлов

Считает SHA256-хэши файлов в папке и сохраняет манифест для дальнейшего сравнения.

БезопасностьХэшиКонтроль изменений
New-FileHashManifest.ps1
$Path = 'C:\ImportantFiles'
$Manifest = 'C:\Temp\hash-manifest.csv'

Get-ChildItem $Path -Recurse -File |
    Get-FileHash -Algorithm SHA256 |
    Select-Object Path, Hash, Algorithm |
    Export-Csv $Manifest -NoTypeInformation -Encoding UTF8

Write-Host "Manifest saved: $Manifest"

Лучшие практики PowerShell

PowerShell-скрипт в администрировании должен быть не просто рабочим, а безопасным, понятным, повторяемым и пригодным для запуска другим человеком.

1. Используйте полные имена команд

В интерактивной консоли можно писать ls и ?, но в скриптах лучше Get-ChildItem и Where-Object.

2. Добавляйте -WhatIf

Для опасных операций сначала проверяйте эффект: удаление, изменение AD, реестра, служб, файлов.

3. Логируйте действия

Минимум: Start-Transcript или запись в лог через Out-File -Append.

4. Обрабатывайте ошибки

Используйте try/catch, -ErrorAction Stop и понятные сообщения об ошибках.

5. Не храните пароли в коде

Не вставляйте пароли открытым текстом. Используйте безопасные хранилища, Managed Service Accounts или секреты.

6. Делайте параметры

Скрипт с param() проще переиспользовать, тестировать и запускать из планировщика.

Шаблон аккуратного скрипта

Script template
<#
.SYNOPSIS
    Краткое описание скрипта.
.DESCRIPTION
    Подробное описание, что делает скрипт и какие есть ограничения.
.EXAMPLE
    .\Script.ps1 -Path C:\Logs -Days 30
#>

[CmdletBinding(SupportsShouldProcess = $true)]
param(
    [Parameter(Mandatory = $true)]
    [string]$Path,

    [int]$Days = 30
)

$ErrorActionPreference = 'Stop'
$LogPath = "C:\Temp\script-$(Get-Date -Format 'yyyyMMdd-HHmmss').log"
Start-Transcript -Path $LogPath

try {
    if (-not (Test-Path $Path)) {
        throw "Путь не найден: $Path"
    }

    $Files = Get-ChildItem $Path -Recurse -File |
        Where-Object LastWriteTime -lt (Get-Date).AddDays(-$Days)

    foreach ($File in $Files) {
        if ($PSCmdlet.ShouldProcess($File.FullName, 'Remove old file')) {
            Remove-Item $File.FullName -Force
        }
    }
}
catch {
    Write-Error "Ошибка: $($_.Exception.Message)"
}
finally {
    Stop-Transcript
}

Чек-лист перед запуском скрипта в проде

  1. Проверить, что скрипт не содержит паролей, токенов и лишних прав.
  2. Запустить в тестовой среде или на одном пилотном сервере.
  3. Использовать -WhatIf для операций изменения.
  4. Проверить права запуска и контекст: пользователь, SYSTEM, сервисная учётка.
  5. Добавить логирование результата и ошибок.
  6. Проверить кодировку файлов: для русского текста использовать UTF‑8.
  7. Подготовить план отката, если скрипт меняет AD, реестр, службы или файлы.
Главный принцип: сначала получить данные через Get-*, затем отфильтровать, потом проверить через -WhatIf, и только после этого выполнять изменение через Set-*, New-*, Remove-* или Restart-*.