Napraw polskie znaki w PowerShell

Skrypt zapisuje Ä… albo ? zamiast ą, a konsola pokazuje krzaki? Windows PowerShell 5.1 używa różnego kodowania zależnie od polecenia. Poniżej przyczyny i właściwe parametry – a zepsute pliki naprawisz w przeglądarce powyżej.

Działa z tekstem i plikami:

  • CSV
  • TXT
  • JSON
  • XML
  • SRT
  • VTT
  • SMI
  • TSV
  • MD
  • HTML
  • SQL
  • LOG

Na przykład eksporty z Excela, zrzuty baz danych, napisy do filmów lub kod stron.

Napraw

  1. Przeciągnij plik lub wklej tekst
  2. Naprawa następuje automatycznie
  3. Skopiuj lub pobierz
albo po prostu przeciągnij plik tutaj

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.

Plik UTF-8 odczytany przez Get-Content w PowerShell 5.1

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 UTF8 czyta pliki UTF-8 poprawnie także bez BOM.
  • Set-Content, Out-File i Add-Content zapisują UTF-8 z -Encoding UTF8 – w wersji 5.1 zawsze z BOM.
  • Export-Csv dane.csv -Encoding UTF8 -NoTypeInformation zamiast 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.

Więcej poradników