Sedno problemu: każde polecenie ma inne kodowanie
W Windows PowerShell 5.1 prawie każde polecenie ma własne kodowanie domyślne: Get-Content czyta pliki bez BOM jako ANSI (na polskim Windows to Windows-1250), Out-File i > zapisują UTF-16, Set-Content zapisuje ANSI, a Export-Csv ASCII. PowerShell 7 ujednolicił to i wszędzie używa UTF-8 bez BOM.
Przed
Użytkownik;Dział;Oddział Żaneta Wójcik;Sprzedaż;Kraków Zbigniew Kowalski;Zakupy;Gdańsk
Po
Użytkownik;Dział;Oddział Żaneta Wójcik;Sprzedaż;Kraków Zbigniew Kowalski;Zakupy;Gdańsk
Poprawnie czytaj i zapisuj pliki
Get-Content dane.csv -Encoding UTF8czyta pliki UTF-8 poprawnie także bez BOM.Set-Content,Out-FileiAdd-Contentzapisują UTF-8 z-Encoding UTF8– w wersji 5.1 zawsze z BOM.Export-Csv dane.csv -Encoding UTF8 -NoTypeInformationzamiast domyślnego ASCII, które zamienia polskie litery na?.- Dla wszystkich poleceń naraz:
$PSDefaultParameterValues['*:Encoding'] = 'utf8'na początku skryptu.
Zapytania Invoke-RestMethod i Invoke-WebRequest
Jeśli serwer nie podaje zestawu znaków w nagłówku Content-Type, Windows PowerShell 5.1 dekoduje odpowiedź jako ISO-8859-1. Odpowiedzi w UTF-8 zawierają wtedy Ä… i Å‚. Rozwiązanie: pobierz odpowiedź jako bajty i zdekoduj ją sam, np. [Text.Encoding]::UTF8.GetString((Invoke-WebRequest $url).RawContentStream.ToArray()).
Pliki skryptów z polskimi znakami
Jeśli zapiszesz skrypt jako UTF-8 bez BOM, Windows PowerShell 5.1 odczyta go jako ANSI. Litery w tekstach typu Write-Host "Zażółć" wyglądają wtedy jak Zażółć. Zapisuj pliki .ps1 jako UTF-8 z BOM – w VS Code przez kodowanie na pasku stanu, w Notepad++ przez Encoding → UTF-8-BOM.
Konsola
Jeśli tylko okno konsoli pokazuje dziwne znaki, np. ramki zamiast polskich liter, plik często jest w porządku – konsola czyta UTF-8 jako DOS-ową stronę kodową 852. Przełącz wyjście przez [Console]::OutputEncoding = [Text.Encoding]::UTF8. Dla danych przekazywanych do programów zewnętrznych ustaw też $OutputEncoding = [Text.Encoding]::UTF8.
Jeśli plik został już zapisany z błędem, przeciągnij go do pola powyżej: Mojibuster naprawia Ä… i podobne oraz zamienia pliki ANSI (Windows-1250) na UTF-8. Jeśli plik zawiera już znaki zapytania, tekst jest utracony – zobacz co to jest mojibake.
Najczęstsze pytania
Jaką wersję PowerShell mam?
Pokaże to $PSVersionTable.PSVersion. 5.1 to Windows PowerShell wbudowany w system, od wersji 7 nazywa się po prostu PowerShell i domyślnie używa UTF-8.
Dlaczego Excel źle otwiera mój plik CSV z PowerShell?
PowerShell 7 zapisuje UTF-8 bez BOM, którego Excel nie rozpoznaje. Użyj -Encoding utf8BOM albo zapisz plik z BOM w Mojibuster. Więcej w artykule o Excelu i krzakach w CSV.
Czy potrzebuję chcp 65001?
Tylko dla programów, które trzymają się strony kodowej konsoli. W samym PowerShell wystarczy [Console]::OutputEncoding.