О 02:13 файловий сервер «повільний», команда додатку «заблокована», і ви дивитеся на Windows-машину, яка здається, ніби йде крізь сироп. Ви відкриваєте консоль, набираєте щось просте за звичкою, і це працює — або не працює, бо ви вибрали не той шелл у цей момент.
Це не релігійна війна. Це вибір інструменту під тиском. PowerShell — сучасний робочий кінь. CMD — тарган адміністрування Windows: дратівливо витривалий, важко вбивний і все ще в стінах, коли світло згасає.
Справжня різниця: об’єкти проти тексту (і чому це важливо для операційників)
CMD — це текстовий конвеєр. PowerShell — це конвеєр об’єктів. Це заголовок, але операційні наслідки — те, що піднімає тиск крові.
Контракт CMD: рядки скрізь
В CMD майже все, що ви робите — «запустити програму, отримати текст, розпарсити текст, сподіватися, що текст не зміниться». Деякі утиліти вбудовані (наприклад dir), інші — класичні EXE (наприклад ipconfig), і сумне число просто «друкує те, що друкує». Це і обмеження, і суперсила: текст універсальний, а CMD присутній навіть коли машина напівзламана.
Контракт PowerShell: структуровані дані, потім форматування
PowerShell передає .NET-об’єкти, а не рядки, через конвеєр. Кмдлети видають об’єкти зі властивостями; форматування відбувається в кінці. Це означає, що ви можете фільтрувати надійно (Where-Object), точно вибирати поля (Select-Object) і експортувати чисто (ConvertTo-Json, Export-Csv). Ви перестаєте писати регулярні вирази, щоб знайти «третій токен після двокрапки». Ви перестаєте боятися локалізації, змін у відступах і ширини колонок.
Але модель об’єктів PowerShell має ціну: час запуску, завантаження модулів, скрипти профілю, політики виконання і іноді такий тип помилки, де шелл в порядку, але бракує модуля і ваша «проста» команда перетворюється на полювання за залежностями.
Операційна реальність: вибирайте шелл відповідно до домену відмов
- Якщо ви в режимі відновлення, обмежений інтерфейс або мінімальне середовище: CMD часто працює, коли PowerShell відсутній або скривлений.
- Якщо вам потрібна коректність у масштабі, віддалена оркестрація, інвентаризація або щось відтворюване: PowerShell — безпечніший вибір.
- Якщо ви виконуєте швидку інтерактивну тріаж: може підійти будь-який, але оберіть той, що зменшує когнітивне навантаження на цій машині.
Одна перефразована ідея (не дослівно) від співавтора Google SRE Niall Murphy: надійність походить від проектування систем, які відмовляють у передбачуваний спосіб, який ви відрепетирували
. Вибір шелла — частина цієї репетиції.
Коли CMD все ще перемагає
1) WinRE, Безпечний режим і «я не можу завантажити свої красиві іграшки»
Коли Windows у середовищі відновлення, вам потрібно мінімальне поле для помилок. CMD доступний у більшій кількості місць і має менше рухомих частин. Якщо машині не вдається завантажитись, ви не для того, щоб милуватись об’єктними конвеєрами; ви тут, щоб змусити її стартувати.
2) Вам потрібні класичні утиліти в їх первісному вигляді
Багато діагностик Windows досі — класичні EXE: wevtutil, netsh, sc, robocopy, diskpart, bcdedit. PowerShell також може викликати їх, але правила цитування в CMD часто відповідають прикладам у рунабуках і старих інцидентних документах.
3) Час запуску має значення (так, іноді має)
CMD відкривається швидко, навіть на навантаженому хості. PowerShell теж може бути швидким, але модулі, профілі та корпоративні засоби контролю кінцевих точок іноді роблять його повільнішим. Коли ви швидко ітераціонуєте — протестував зміну, повторив перевірку — затримка має значення.
4) Пакетні файли все ще повсюдні (і деякі критично важливі)
Якщо у вашій організації 15-річна «склейка» для розгортання, це, ймовірно, .bat або .cmd, що використовує if errorlevel і деякий крихкий парсинг. Переписувати іноді розумно, але не завжди це сьогоднішня проблема.
5) Ви маєте справу з дуже старими версіями Windows або заблокованими хостами
PowerShell 5.1 поширений, PowerShell 7 не універсальний, і деякі захищені сервери ставляться до PowerShell як до зарядженої зброї. CMD зазвичай дозволений, бо він «просто шелл», що наївно, але операційно зручно.
Короткий жарт №1: CMD — як ручна коробка передач: менше функцій, більше контролю, і всі клянуться, що вміють ним керувати, поки не почнуть підйом.
Коли перемагає PowerShell (більшість днів)
1) Все, що включає структурований запит
Якщо вам потрібно «усі служби, які Automatic, але не Running» або «усі диски з менше ніж 10% вільного», PowerShell перетворює це на одну надійну команду. CMD перетворює це на парсинг текстового виводу і сподівання, що ваш regex не з’їсть пробіл.
2) Віддалене адміністрування в масштабі
PowerShell Remoting (WinRM / WSMan) дає стандартний спосіб запуску команд віддалено, правильної автентифікації та повернення структурованих результатів. CMD може робити віддалене виконання через сторонні інструменти, завдання або хаки епохи WMI, але PowerShell — перший клас тут.
3) Безпечніша автоматизація та ідемпотентність
Коли ви пишете PowerShell дисципліновано — явні параметри, обробка помилок, -WhatIf для підтримуваних cmdlet-ів і послідовне логування — ви можете будувати відтворювані операції. Batch теж може бути відтворюваним, але його семантика помилок — болото: коди виходу губляться, конвеєри ховають відмови, а відкладене розширення — окреме коло пекла.
4) Сучасні API управління Windows
Нові поверхні управління з’являються в PowerShell першими: CIM/WMI-кмдлети, cmdlet-и для зберігання, Hyper-V, Defender та інструменти безпеки, інтеграція з хмарними агентами. CMD — не місце інновацій.
5) Вивід, який можна передати іншим системам
Коли ваше реагування на інциденти очікує JSON, або аудит хоче CSV, PowerShell робить це буденно. CMD може теж, але це більше схоже на вирізання скрипки з піддону для відправки вантажу.
Короткий жарт №2: Конвеєр PowerShell чудовий, поки ви не зрозумієте, що ваш «однолайнер» перетворився на повість з поворотом сюжету в Select-Object.
Цікаві факти та історичний контекст (те, що досі важливо)
- CMD походить від MS-DOS і процесора команд NT; це по суті найстаріший послідовно релевантний інтерфейс адміністрування Windows.
- PowerShell починався як «Monad», створений щоб вирішити проблему «парсинг тексту як API», проштовхуючи об’єкти через конвеєри.
- PowerShell побудований на .NET, тому ви можете звертатися до глибоких системних API (і саме це робить запуск і завантаження модулів нетривіальними).
- Вбудовані CMD проти зовнішніх програм: команди як
dirіset— вбудовані в шелл, тоді якipconfig— виконуваний файл; це важливо, коли PATH зламаний. - Утиліти Windows часто тримали стабільність виводу десятиліттями; ця стабільність — чому стільки крихких скриптів все ще працюють.
- Політика виконання стала полем корпоративних боїв: організації використовували її як контроль, іноді неправильно розуміючи, що вона насправді забороняє.
- PowerShell 5.1 — це «Windows PowerShell» (вбудований на багатьох системах), тоді як PowerShell 7+ — кросплатформенна лінія «pwsh» — інша середа виконання, інша сумісність модулів.
- WinRM за замовчуванням був вимкнений на багатьох клієнтських системах роками, що гальмувало прийняття віддалення і зберігало звички «віддаленого CMD».
- Дивакуватості batch — артефакти історії: такі речі як семантика
ERRORLEVELі відкладене розширення з’явилися через те, що сумісність вважалася священним обітом.
Практичні завдання: команди, виводи та рішення (12+ вправ)
Це навмисно «реальні операційні» завдання: перевірки, які ви запускаєте під час інцидентів, міграцій та дивних скарг на продуктивність. Кожне завдання містить команду, типовий вивід, що це означає і яке рішення це підштовхує.
Завдання 1: Швидко визначити ОС і контекст завантаження (CMD)
cr0x@server:~$ ver
Microsoft Windows [Version 10.0.17763.5458]
Що це означає: Підтверджує сімейство версій Windows. Корисно, коли поведінка відрізняється між Server 2012/2016/2019/2022.
Рішення: Якщо ви на старих збірках, очікуйте старі PowerShell і старі cmdlet-и для зберігання; обирайте інструменти відповідно.
Завдання 2: Перевірити ім’я хоста та членство в домені (CMD)
cr0x@server:~$ echo %COMPUTERNAME% & echo %USERDOMAIN%
FS-23
CORP
Що це означає: Швидка перевірка ідентифікації; підтверджує, що ви не на неправильній машині і чи виконуєте під доменним контекстом.
Рішення: Якщо домен неправильний або пустий, дослідіть проблеми довіри/автентифікації перед тим, як шукати «затримки мережі».
Завдання 3: Підтвердити підвищені права (CMD)
cr0x@server:~$ whoami /groups | findstr /i "S-1-5-32-544"
BUILTIN\Administrators Alias S-1-5-32-544 Mandatory group, Enabled by default, Enabled group
Що це означає: Ви в локальній групі Administrators; багато операцій зі зберігання/мережі/служб вимагають цього.
Рішення: Якщо немає підвищених прав, перезапустіть як адміністратор перед тим, як звинувачувати «Access is denied» в GPO або засобах безпеки.
Завдання 4: Перевірити IP-конфігурацію і виявити проблеми «неправильної NIC» (CMD)
cr0x@server:~$ ipconfig /all
Windows IP Configuration
Host Name . . . . . . . . . . . : FS-23
Primary Dns Suffix . . . . . . . : corp.example
Ethernet adapter Ethernet0:
DHCP Enabled. . . . . . . . . . : No
IPv4 Address. . . . . . . . . . : 10.40.12.23(Preferred)
Subnet Mask . . . . . . . . . . : 255.255.255.0
Default Gateway . . . . . . . . : 10.40.12.1
DNS Servers . . . . . . . . . . : 10.40.1.10
10.40.1.11
Що це означає: Підтверджує IP, шлюз, DNS. «Preferred» означає, що стек задоволений.
Рішення: Якщо DNS-сервери неправильні або відсутні, виправте розв’язування імен перед тим, як копатися в SMB або AD-міфах.
Завдання 5: Швидка перевірка DNS (CMD)
cr0x@server:~$ nslookup fileshare01
Server: dns01.corp.example
Address: 10.40.1.10
Name: fileshare01.corp.example
Address: 10.40.12.55
Що це означає: Ім’я резольвиться, і ви знаєте, який DNS-сервер відповів.
Рішення: Якщо таймаут або резолюція невідповідна, зупиніться. Виправте DNS або застарілі записи; не «оптимізуйте SMB».
Завдання 6: Швидка валідація маршруту (CMD)
cr0x@server:~$ route print | findstr /i "0.0.0.0"
0.0.0.0 0.0.0.0 10.40.12.1 10.40.12.23 25
Що це означає: Маршрут за замовчуванням вказує туди, куди ви думаєте. Метрика показує пріоритет.
Рішення: Якщо маршрут за замовчуванням неправильний (поширено на мультигомедних серверах), виправте маршрути перед тим, як звинувачувати «випадкові таймаути».
Завдання 7: Оцінити базову досяжність і проблеми шляху (CMD)
cr0x@server:~$ ping -n 4 10.40.12.55
Pinging 10.40.12.55 with 32 bytes of data:
Reply from 10.40.12.55: bytes=32 time<1ms TTL=128
Reply from 10.40.12.55: bytes=32 time<1ms TTL=128
Reply from 10.40.12.55: bytes=32 time<1ms TTL=128
Reply from 10.40.12.55: bytes=32 time<1ms TTL=128
Ping statistics for 10.40.12.55:
Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Що це означає: ICMP працює; затримка виглядає локальною. Це не доказ, що додаток працює, але звужує область пошуку.
Рішення: Якщо є втрата пакетів, розглядайте це як проблему мережі, поки не доведено інше; не налаштовуйте скрипти PowerShell.
Завдання 8: Перевірити підключення SMB і стан сесій (CMD)
cr0x@server:~$ net use
New connections will be remembered.
Status Local Remote Network
-------------------------------------------------------------------------------
OK Z: \\fileshare01\dept Microsoft Windows Network
The command completed successfully.
Що це означає: Маєте змонтований диск і він у порядку.
Рішення: Якщо мапінги падають, перевірте облікові дані і синхронізацію часу Kerberos перед тим, як «перезапускати LanmanServer».
Завдання 9: Швидка перевірка вільного місця на диску (CMD)
cr0x@server:~$ wmic logicaldisk get name,freespace,size
FreeSpace Name Size
21474836480 C: 127999999488
1099511627776 D: 2199023255552
Що це означає: Місце в байтах. C: має ~20 GB вільних; D: має ~1 TB.
Рішення: Якщо вільного місця на системному диску мало, очікуйте відмов сервісів, проблем при патчуванні та затримок запису логів. Спершу очистіть.
Завдання 10: Швидка перевірка стану служби (CMD)
cr0x@server:~$ sc query LanmanServer
SERVICE_NAME: LanmanServer
TYPE : 20 WIN32_SHARE_PROCESS
STATE : 4 RUNNING
WIN32_EXIT_CODE : 0 (0x0)
SERVICE_EXIT_CODE : 0 (0x0)
Що це означає: Служба SMB сервер запущена і не повідомляє про помилки.
Рішення: Якщо вона STOPPED або нестабільно запускається, у вас або проблеми з залежностями, або нестача ресурсів; перейдіть до журналів подій і затримки зберігання.
Завдання 11: Запитати недавні критичні системні події (CMD, класично і надійно)
cr0x@server:~$ wevtutil qe System /q:"*[System[(Level=1 or Level=2)]]" /c:5 /f:text
Event[0]:
Log Name: System
Source: disk
Event ID: 7
Level: Error
Description:
The device, \Device\Harddisk2\DR2, has a bad block.
Що це означає: Шар диска повідомляє про погані блоки. Це не «мережа». Це не «PowerShell повільний». Це зберігання.
Рішення: Ескалюйте до обладнання/зберігання негайно; припиніть займатись «налаштуванням продуктивності». Зберіть SMART/діагностику від вендора і плануйте заміну.
Завдання 12: Отримати процеси-«пожирачі CPU» (PowerShell)
cr0x@server:~$ powershell -NoProfile -Command "Get-Process | Sort-Object CPU -Descending | Select-Object -First 5 Name,Id,CPU,WorkingSet64"
Name Id CPU WorkingSet64
sqlservr 4216 9883 12728471552
MsMpEng 1712 622 398524416
svchost 1100 401 172425216
w3wp 5024 389 612978688
System 4 201 89579520
Що це означає: CPU — накопичувальний час від старту процесу. WorkingSet64 — пам’ять у байтах.
Рішення: Якщо Defender (MsMpEng) гарячий під час інциденту файлового сервера, розгляньте виключення для путів з високим навантаженням — обережно, з погодженням безпеки.
Завдання 13: Визначити топ споживачів пам’яті (PowerShell)
cr0x@server:~$ powershell -NoProfile -Command "Get-Process | Sort-Object WorkingSet64 -Descending | Select-Object -First 5 Name,Id,@{n='WS_GB';e={[math]::Round($_.WorkingSet64/1GB,2)}}"
Name Id WS_GB
sqlservr 4216 11.85
w3wp 5024 0.57
MsMpEng 1712 0.37
explorer 3120 0.22
svchost 1100 0.16
Що це означає: Показує working set у GB. Добре для швидкої перевірки «чи машина сторінгує сама себе?».
Рішення: Якщо тиск пам’яті високий і підозрюється пейджинг, підтвердіть лічильниками продуктивності перед поспішним перезапуском сервісів.
Завдання 14: Перевірити стан дисків і розмітку (PowerShell storage cmdlets)
cr0x@server:~$ powershell -NoProfile -Command "Get-PhysicalDisk | Select-Object FriendlyName,MediaType,HealthStatus,OperationalStatus,Size"
FriendlyName MediaType HealthStatus OperationalStatus Size
NVMe0 SSD Healthy OK 1024 GB
SAS01 HDD Warning OK 4000 GB
SAS02 HDD Healthy OK 4000 GB
Що це означає: Стек зберігання бачить диск у Warning. Це часто прогнозована відмова, а не помилкове сповіщення.
Рішення: Якщо будь-який диск у стані Warning/Unhealthy, припиніть налаштування продуктивності і стартуйте управління відмовами: перевірте стан RAID, гарячі спреї, відновлення, бекапи.
Завдання 15: Виміряти лічильники продуктивності SMB швидко (PowerShell)
cr0x@server:~$ powershell -NoProfile -Command "Get-Counter '\SMB Server Shares(*)\Avg. sec/Read' -SampleInterval 1 -MaxSamples 3 | Select-Object -ExpandProperty CounterSamples | Select-Object Path,CookedValue"
Path CookedValue
\\FS-23\SMB Server Shares(dept)\Avg. sec/Read 0.0021
\\FS-23\SMB Server Shares(dept)\Avg. sec/Read 0.0019
\\FS-23\SMB Server Shares(dept)\Avg. sec/Read 0.0450
Що це означає: Затримка читання в основному нормальна, але в одному зразку пікове значення 45ms. Це пахне бекендовим зберіганням або фільтр-драйверами.
Рішення: Якщо піки латентності корелюють зі скаргами користувачів, перейдіть до черги/латентності диска і AV/фільтр-драйверів, а не «прапорців SMB».
Завдання 16: Перевірити синхронізацію часу (Kerberos і «таємничі помилки автентифікації») (CMD)
cr0x@server:~$ w32tm /query /status
Leap Indicator: 0(no warning)
Stratum: 4 (secondary reference - syncd by (S)NTP)
Precision: -23 (119.209ns per tick)
Last Successful Sync Time: 2/5/2026 1:52:10 AM
Source: dc01.corp.example
Poll Interval: 6 (64s)
Що це означає: Машина синхронізована нещодавно та з розумного джерела.
Рішення: Якщо час дрейфує або джерело неправильне, виправте час перед тим, як шукати «погані облікові дані» і «проблеми SPN».
Завдання 17: Перевірити готовність WinRM для PowerShell remoting (CMD)
cr0x@server:~$ winrm quickconfig
WinRM service is already running on this machine.
WinRM is already set up for remote management on this computer.
Що це означає: Базова конфігурація віддаленого доступу налаштована.
Рішення: Якщо це не вдається, плануйте альтернативний доступ (RDP/консоль) або виправте remoting перед тим, як обіцяти «ми можемо виконати це на 500 серверах».
Завдання 18: Отримати встановлену версію PowerShell і видання (PowerShell)
cr0x@server:~$ powershell -NoProfile -Command "$PSVersionTable | Select-Object PSVersion,PSEdition"
PSVersion PSEdition
--------- ---------
5.1.17763.5458 Desktop
Що це означає: Це Windows PowerShell 5.1 (Desktop edition), а не PowerShell 7+ (Core).
Рішення: Не припускайте сумісності з кросплатформеними модулями або сучасним синтаксисом. Пишіть скрипти так, щоб вони працювали в 5.1 або свідомо доставляйте pwsh.
План швидкої діагностики: знайти вузьке місце швидко
Це послідовність, яку я використовую, коли хтось каже «PowerShell повільний» або «CMD швидший», але система насправді задихається з іншої причини. Мета — визначити обмежальний ресурс за хвилини, а не вигравати суперечку.
Перший крок: підтвердьте середовище і вашу опору
- Ви підвищені? Якщо ні, половина ваших перевірок бреше або просто завершиться помилкою.
- Ви в правильному шеллі і версії? PowerShell 5.1 vs 7 змінює доступність модулів; профілі можуть додавати секунди затримки.
- Чи хост здоровий настільки, щоб його діагностувати? Якщо йому бракує місця на C: або пам’яті, будь-який інструмент відчувається повільним.
Другий крок: визначте, це CPU, пам’ять, диск чи мережа
- CPU: Шукайте топ-споживача, що відповідає вікну скарги (сканування AV, стиснення, програма, що втекла).
- Пам’ять: Високий commit/paging робить шелли «завислими», поки система трясе.
- Диск: Пікові затримки і глибина черги змушують усе завмирати — особливо завантаження модулів PowerShell і читання профілів.
- Мережа: Затримки DNS і автоналаштування проксі — класичні причини «PowerShell повільний», бо багато команд тригерять розв’язування імен або перевірки сертифікатів.
Третій крок: ізолюйте накладні витрати шелла від системних
- Запустіть PowerShell з
-NoProfileщоб виключити повільні профілі і скрипти. - Заміряйте один простий кмдлет (наприклад
Get-Date) проти модуль-важкого кмдлету (наприклад для зберігання/мережі). Якщо обидва повільні, то не в модулі справа. - Викличте той же EXE з обох шеллів (наприклад,
ipconfig). Якщо повільно в обох, винуватець — система або залежності EXE.
Четвертий крок: підтвердьте шлях залежностей (на що чекає ваша команда?)
- DNS: повільна резолюція може блокувати віддалені виклики.
- Автентифікація: дрейф часу або затримка AD може загальмовувати remoting.
- Зберігання: повільні читання блокують усе від імпорту модулів до запитів журналів подій.
- Засоби безпеки: сканування скриптів і AMSI-hook-и можуть додавати значний оверхед.
Три міні-історії з корпоративного світу (біль, жаль і одна тиха перемога)
Міні-історія №1: Інцидент через хибне припущення
Команда мала рунабук, який починався з простої істини: «Використовуйте PowerShell для всього». Це була модернізація, і вона в основному спрацювала. Тож коли контролер домену не зміг завантажитись після патча, інженер на чергуванні пішов за рунабуком — відкрив PowerShell у режимі відновлення, спробував завантажити звичні інструменти і вдарився у стіну. Середовище не містило того, що припускав рунабук.
Вони витратили час, намагаючись монтувати модулі і запускати кмдлети, яких не було. Натомість реальна потреба була базова: перевірити конфігурацію завантаження, підтвердити букви томів у WinRE (які люблять зміщуватись) і відкотити поганий драйвер. CMD міг зробити все це вбудованими командами та класичними утилітами.
Врешті-решт хтось старший запитав «в якому ви шеллі?» і переключився на CMD. Використали bcdedit та базові файлові операції, щоб перевірити записи завантаження і помітити невідповідність між очікуваним та фактичним відображенням томів. Після цього усе було механічно: виправити посилання завантаження, підтвердити правильний системний hive, перезавантажитись.
Постмортем не був про те, що PowerShell поганий. Він був про припущення щодо наявності вашого улюбленого середовища у саме той момент, коли вам потрібен найменший ланцюг залежностей. Виправлення було простим і нудним: рунабук отримав гілку «Recovery mode», яка за замовчуванням переходить на CMD і перелічує кілька команд, що реально працюють у цьому контексті.
Міні-історія №2: Оптимізація, яка вдарила у відповідь
Група платформи хотіла швидшого збору логів під час інцидентів. В них був PowerShell-скрипт, що запитував журнали подій, фільтрував за часом і експортував результати у JSON для внутрішнього інструменту. Це працювало, але не було достатньо швидко при запуску на багатьох хостах.
Тож вони «оптимізували», замінивши структуровані запити подій на підхід, що виглядав швидшим: викликати wevtutil з PowerShell і парсити текст. На кількох машинах бенчмарк показав покращення. Вони запустили це в прод.
Два місяці по тому, під час збою, колектор повернув порожні результати для частини серверів у іншій локалі. Текстовий вивід мав трохи інше форматування. Регекс не спрацював. Команда інциденту марнувала час, бо дашборд показував «нема помилок», тоді як сервери кричали в системному журналі.
Вони відкотилися до об’єктно-орієнтованого підходу і потім оптимізували правильно: зменшили область запиту, використали серверну фільтрацію де можливо і батчували віддалені виклики. Урок: хакі продуктивності, які торгують структурою заради швидкості парсингу, часто відпадають боком у найгірший момент — коли вам потрібні однозначні дані.
Міні-історія №3: Нудна, але правильна практика, що врятувала день
Інша компанія, інший парк серверів, завантажених зберіганням. Їхні файлові сервери були стабільні, але команда мала звичку: на кожному сервері був маленький «тріаж-кит» документований у простому текстовому файлі, збереженому локально і надрукованому в системі рунабуків. Він включав і CMD, і PowerShell команди, кожна обрана для середовища, де вона найнадійніша.
Під час інциденту, суміжного з рансомваром, політика безпеки швидко загострилась. Виконання PowerShell-скриптів було сильно обмежене, і деякі віддалені інструменти були заблоковані політиками. Інженери на чергуванні все ще могли зайти, але багато автоматичних шляхів були відрізані.
Тріаж-кит не переймався. Він покладався на прямі локальні перевірки: стан служб через sc, мережа з ipconfig і route, вибірка журналів подій через wevtutil та перевірки стану зберігання через PowerShell у режимі -NoProfile для мінімального оверхеду. Вони могли визначити, які хости торкнуті, які здорові і де вузьке місце (латентність диска та фільтр-драйвери) без боротьби з шаром політик.
Ніяких геройств. Ніякої хитрості. Просто відпрацьована, мінімально залежна послідовність діагностики, що працює під тиском. Це той нудний підхід, який ви хочете.
Типові помилки: симптом → корінна причина → виправлення
1) «PowerShell повільно відкривається»
Симптом: Консоль відкривається, але проходить кілька секунд перед тим, як вона приймає введення.
Корінна причина: Важкі скрипти профілю, автозавантаження модулів або сканування шляхів профілю/модулів засобами безпеки.
Виправлення: Використовуйте powershell -NoProfile для інцидентної роботи. Аудитуйте вміст $PROFILE і видаляйте дорогі імпорти. Якщо засоби безпеки підключають сканування скриптів, координуйте виключення для відомо безпечних адміністративних скриптів — не робіть широких загальних виключень.
2) «Мій скрипт працює в PowerShell, але не в CMD»
Симптом: Команди з лапками і дужками поводяться по-різному; змінні не розгортаються.
Корінна причина: Різні правила цитування і розгортання змінних. CMD використовує %VAR% і має пастки відкладеного розширення; PowerShell використовує $var і по-іншому трактує рядки.
Виправлення: Не вставляйте синтаксис PowerShell у CMD і навпаки. Якщо потрібно викликати один шелл з іншого, робіть це явно і тримайте аргументи простими.
3) «Конвеєр CMD не відпрацював, але завдання не виконалось»
Симптом: Пакетний файл продовжує роботу навіть після помилки команди; логи показують приблизно успішний текст.
Корінна причина: Коди виходу губляться у конвеєрах або перезаписуються наступними командами; неправильне використання ERRORLEVEL.
Виправлення: Перевіряйте if errorlevel 1 одразу після команди. Уникайте пайпінгу, коли вам потрібен точний код виходу. Розгляньте обгортання критичних кроків у PowerShell, де обробка помилок більш контрольована.
4) «PowerShell remoting не працює, але RDP працює»
Симптом: Enter-PSSession або Invoke-Command повертають помилки доступу/транспорту.
Корінна причина: WinRM не налаштований, відсутні правила фаєрвола, проблеми SPN/Kerberos або обмежена делегація.
Виправлення: Перевірте конфіг WinRM локально за допомогою winrm quickconfig. Підтвердіть DNS і синхронізацію часу. Перевірте політику фаєрвола. Якщо корпоративна політика блокує WinRM, використовуйте альтернативні підтримувані методи віддалення і документуйте їх.
5) «Парсинг тексту зламався після патчу»
Симптом: Пакетний скрипт, який скрапить вивід з net/sc/wevtutil, раптово повертає порожні дані.
Корінна причина: Форматування виводу змінилося тонко; відрізняються локальні налаштування; колонки перенеслися.
Виправлення: Припиніть парсити орієнтований на людину вивід де можливо. У PowerShell використовуйте кмдлети, що повертають об’єкти. Якщо парсити потрібно, обмежте локаль і використовуйте стабільні формати (CSV/JSON), коли вони доступні.
6) «PowerShell каже access denied навіть як адміністратор»
Симптом: Адмін може запускати CMD-інструменти, але kmdlet-и PowerShell падають.
Корінна причина: Проблеми з токеном UAC, Constrained Language Mode, політики AppLocker/WDAC або відсутні привілеї в контексті процесу.
Виправлення: Перевірте підвищення прав, мову виконання, і тестуйте з -NoProfile. Якщо діє політика контролю додатків, працюйте з командою безпеки для затвердження підписаних скриптів і відомих адміністративних бінарів.
Контрольні списки / покроковий план
Контрольний список: як обирати CMD чи PowerShell у моменті
- Ви в WinRE/Безпечному режимі/мінімальному середовищі? Обирайте CMD за замовчуванням.
- Вам потрібне структуроване фільтрування/звітність/експорт? Обирайте PowerShell.
- Система нестабільна (помилки диска, тиск пам’яті)? Віддайте перевагу шляху з найменшим оверхедом: CMD + цільові утиліти; PowerShell лише з
-NoProfile. - Працюєте віддалено на багатьох хостах? Віддайте перевагу PowerShell remoting, але перед тим перевірте WinRM і політику.
- Завдання — класична утиліта? Використайте утиліту напряму; не загортайте її, якщо вам не потрібна структура і парсинг можна підтримати надійно.
Покроково: побудуйте «двоштучний» рунабук, що переживе інциденти
- Напишіть кожну критичну перевірку двічі: один метод сумісний з CMD, інший — з PowerShell. Визначіть авторитетний і підпишіть fallback.
- Стандартизуйте виклик PowerShell: використовуйте
-NoProfileв рунабуках, якщо вам явно не потрібен профіль. - Логуйте сирі виводи для форензики: зберігайте точну команду і вивід у тикеті/нотах інциденту.
- Визначте мінімальний діагностичний набір: ідентифікація, синхронізація часу, DNS, маршрут, вільне місце на диску, помилки журналу подій, стан служб.
- Тренуйте в деградованих режимах: тестуйте рунабук на VM у Безпечному режимі або в умовах «диск повний». Саме тут припущення вмирають.
- Майте тригер ескалації: «Якщо диск у Warning/Unhealthy або в System journal є помилки диска, зупиніть і залучіть зберігання/обладнання».
Покроково: переписуємо крихкий пакетний процес у PowerShell без поломки продакшену
- Зафіксуйте поведінку: зберіть поточні входи/виводи і коди виходу. Якщо ви не знаєте, як виглядає «успіх», ви впровадите регресію.
- Замініть парсинг спочатку: перейдіть від текстового скрапінгу до об’єктних запитів, де можливо.
- Робіть помилки голосними: встановіть жорстку обробку помилок у скрипті і поверніть осмислені коди виходу викликачам.
- Запускайте поруч: запускайте PowerShell-версію в режимі «спостереження», поки пакетний процес все ще робить реальну роботу.
- Переходьте поступово: спочатку на невеликій групі серверів; порівнюйте результати.
- Задокументуйте відкат: в операціях відкат — це функція, а не визнання поразки.
Питання та відповіді
1) Чи застарів CMD?
Ні. Воно старе, але не мертве. CMD досі найнадійніша базова опція, коли Windows у зменшеному стані, і багато базових утиліт все ще «з епохи CMD».
2) Чи варто припинити писати пакетні файли?
Для нової автоматизації: так, здебільшого. Використовуйте PowerShell для всього, що потребує коректності, структури і підтримуваності. Залишайте пакетні файли для glue у обмежених середовищах і для спадщини, де переписати означає ризик.
3) Чому PowerShell іноді здається повільнішим навіть для простої команди?
Накладні витрати на старт (профілі, виявлення модулів), сканування безпеки і ініціалізація .NET можуть домінувати над «простими» операціями. Використовуйте -NoProfile для інцидентної роботи і уникайте важкої кастомізації профілів на серверах.
4) Чи може PowerShell запускати CMD-команди?
Так — PowerShell може запускати будь-який виконуваний файл. Але будьте обережні з цитуванням і з командами, які є вбудованими в шелл (наприклад dir), бо PowerShell може мати аліаси або інше трактування.
5) Яка найбільша практична різниця в скриптуванні?
Обробка помилок і типи даних. PowerShell дозволяє працювати зі структурованими об’єктами і ловити виключення. Batch змушує виводити стан з тексту і кодів виходу, що більш крихко.
6) Чи завжди PowerShell remoting — найкращий варіант для віддалення?
Це найчистіший нативний варіант для Windows, коли WinRM доступний і політика дозволяє. У заблокованих середовищах можуть бути потрібні інші затверджені методи. Помилка — припускати, що remoting увімкнений скрізь.
7) Мені потрібен PowerShell 7?
Не обов’язково. Багато адміністративних модулів таргетять 5.1. PowerShell 7 відмінний для кросплатформених сценаріїв і покращень продуктивності, але сумісність модулів і реалії корпоративного розгортання мають значення.
8) Як уникнути пастки «скрипт PowerShell заблокований політикою» під час інцидентів?
Майте план, що не залежить від запуску непідписаних скриптів ad-hoc. Використовуйте підписані скрипти для стандартної автоматизації, тримайте CMD-резерв для основного тріажу і документуйте, як запускати PowerShell з мінімальними залежностями.
9) Чи завжди парсинг тексту — погано?
Ні, просто ризиковано. В надзвичайних ситуаціях парсинг тексту може бути прагматичним. Для довготривалої автоматизації віддавайте перевагу структурованим виводам і об’єктним запитам, бо «працює сьогодні» — не стратегія надійності.
Наступні кроки, які можна застосувати
Припиніть питати «Який шелл кращий?». Питайте «Який шелл менше відмовляє для цього сценарію?». PowerShell має бути за замовчуванням для автоматизації, звітності і масштабу. CMD — резервна опція для відновлення, мінімальних середовищ і тих класичних утиліт, які досі говорять правду, коли все інше горить.
Зробіть це далі:
- Створіть двоштучний тріаж-кит для основних ролей серверів (файловий, веб, БД, контролери домену). Тримайте його коротким і виконуваним.
- Стандартизуйте використання PowerShell в інцидентах:
-NoProfile, явні параметри і чисті виводи. - Позбудьтеся крихкого парсингу з часом: замініть скрапінг тексту на об’єктні запити, але не «оптимізуйте», роблячи дані менш надійними.
- Практикуйте в деградованих режимах: WinRE, мало диска, обмежена політика. Саме там CMD досі виправдовує себе.
Якщо ви зробите ці чотири речі, ви витрачатимете менше часу на боротьбу з інструментами і більше — на виправлення системи. Адже це і є ваша робота.