Корень проблемы: у каждой команды своя кодировка
В 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.