Корінь проблеми: у кожної команди своє кодування
У Windows PowerShell 5.1 майже кожна команда має власне кодування за замовчуванням. Get-Content читає файл без BOM як ANSI (в українській Windows це Windows-1251), Out-File і > пишуть UTF-16, Set-Content пише ANSI, а Export-Csv — ASCII, тож українські літери стають ?. У PowerShell 7 усе уніфіковано: скрізь UTF-8 без BOM.
До
Працівник;Відділ;Місто Іван Шевченко;Продажі;Дніпро Олена Гриценко;Закупівлі;Запоріжжя
Після
Працівник;Відділ;Місто Іван Шевченко;Продажі;Дніпро Олена Гриценко;Закупівлі;Запоріжжя
Правильно читаємо й пишемо файли
Get-Content data.csv -Encoding UTF8читає UTF-8 правильно, навіть без BOM.- Якщо файл у Windows-1251 і ви хочете прочитати його явно, у PowerShell 7 вкажіть
-Encoding windows-1251. У Windows PowerShell 5.1 для цього є-Encoding Default: так використовується ANSI-кодування системи. Set-Content,Out-FileтаAdd-Contentпишуть UTF-8 із параметром-Encoding UTF8. У версії 5.1 це завжди UTF-8 з BOM.Export-Csv data.csv -Encoding UTF8 -NoTypeInformation -Delimiter ";"замість ASCII за замовчуванням, який замінює українські літери на?. Крапка з комою потрібна, щоб Excel в українській Windows розбив стовпці.- Для всіх команд одразу:
$PSDefaultParameterValues['*:Encoding'] = 'utf8'на початку скрипта.
Веб-запити: Invoke-RestMethod та Invoke-WebRequest
Якщо сервер не вказав кодування в заголовку Content-Type, Windows PowerShell 5.1 декодує відповідь як ISO-8859-1. Тоді у відповіді в UTF-8 з’являються привіт. Отримайте відповідь у вигляді байтів і декодуйте самі: [Text.Encoding]::UTF8.GetString((Invoke-WebRequest $url).RawContentStream.ToArray()).
Файли скриптів з українськими літерами
Якщо зберегти скрипт в UTF-8 без BOM, Windows PowerShell 5.1 прочитає його як ANSI. Тоді рядок Write-Host "Привіт" виведе РџСЂРёРІС–С‚. Зберігайте .ps1 в UTF-8 з BOM: у VS Code через кодування в рядку стану, у Notepad++ через меню кодувань (Encoding) → UTF-8-BOM.
Консоль
Якщо неправильні знаки на кшталт ╨Я╤А╨╕╨▓╤Ц╤В видно лише у вікні консолі, файл часто в порядку: консоль Windows читає UTF-8 як DOS-кодування CP866. Перемкніть вивід командою [Console]::OutputEncoding = [Text.Encoding]::UTF8. Для даних, які ви передаєте зовнішнім програмам, задайте ще й $OutputEncoding = [Text.Encoding]::UTF8.
Якщо файл уже записано з помилкою, перетягніть його в поле вище: Mojibuster виправить РџСЂРёРІС–С‚ і подібне, а файли в ANSI (Windows-1251) переведе в UTF-8. Якщо у файлі вже стоять знаки питання, текст втрачено. Докладніше: що таке кракозябри.
Часті запитання
Яка в мене версія PowerShell?
Її покаже $PSVersionTable.PSVersion. Версія 5.1 — це вбудований у Windows Windows PowerShell. Починаючи із 7 він називається просто PowerShell і за замовчуванням використовує UTF-8.
Чому Excel неправильно відкриває CSV із PowerShell?
PowerShell 7 пише UTF-8 без BOM, а Excel його не розпізнає. Використайте -Encoding utf8BOM або збережіть файл із BOM у Mojibuster. Докладніше: кракозябри в Excel.
Чи потрібна команда chcp 65001?
Лише для програм, які орієнтуються на кодову сторінку консолі. Усередині PowerShell досить [Console]::OutputEncoding.