Jádro problému: každý příkaz má jiné kódování
Ve Windows PowerShellu 5.1 má skoro každý příkaz vlastní výchozí kódování: Get-Content čte soubory bez BOM jako ANSI (v české verzi Windows je to Windows-1250), Out-File a > zapisují UTF-16, Set-Content zapisuje ANSI a Export-Csv ASCII. PowerShell 7 to sjednotil a všude používá UTF-8 bez BOM.
Před
UĹľivatel;OddÄ›lenĂ;PoboÄŤka Jiřà Dvořák;Prodej;TĹ™ebĂÄŤ ZdenÄ›k ÄŚernĂ˝;Nákup;Brno
Po
Uživatel;Oddělení;Pobočka Jiří Dvořák;Prodej;Třebíč Zdeněk Černý;Nákup;Brno
Správné čtení a zápis souborů
Get-Content data.csv -Encoding UTF8čte soubory UTF-8 správně i bez BOM.Set-Content,Out-FileaAdd-Contentzapisují UTF-8 s-Encoding UTF8– ve verzi 5.1 vždy s BOM.Export-Csv data.csv -Encoding UTF8 -NoTypeInformationmísto výchozího ASCII, které nahrazuje české písmena znakem?.- Pro všechny příkazy najednou:
$PSDefaultParameterValues['*:Encoding'] = 'utf8'na začátku skriptu.
Invoke-RestMethod a Invoke-WebRequest
Pokud server neuvede znakovou sadu v hlavičce Content-Type, dekóduje Windows PowerShell 5.1 odpověď jako ISO-8859-1. Odpovědi v UTF-8 pak obsahují Ä› a Å™. Řešení: stáhnout odpověď jako bajty a dekódovat ji sami, například [Text.Encoding]::UTF8.GetString((Invoke-WebRequest $url).RawContentStream.ToArray()).
Soubory skriptů s diakritikou
Uložíte-li skript jako UTF-8 bez BOM, přečte ho Windows PowerShell 5.1 jako ANSI. Písmena v řetězcích jako Write-Host "Příliš žluťoučký kůň" pak vypadají jako PĹ™Ăliš ĹľluĹĄouÄŤkĂ˝ kĹŻĹ. Ukládejte soubory .ps1 jako UTF-8 s BOM – ve VS Code přes kódování ve stavovém řádku, v Notepad++ přes Encoding → UTF-8-BOM.
Konzole
Pokud špatné znaky ukazuje jen okno konzole, např. čáry a rámečky místo písmen, bývá soubor v pořádku – konzole čte UTF-8 jako DOS kódovou stránku 852. Výstup přepnete příkazem [Console]::OutputEncoding = [Text.Encoding]::UTF8. U dat předávaných externím programům nastavte také $OutputEncoding = [Text.Encoding]::UTF8.
Pokud už byl soubor zapsán rozbitě, přetáhněte ho do pole výše: Mojibuster opraví Ä› a podobné znaky a převede soubory ANSI (Windows-1250) na UTF-8. Pokud soubor už obsahuje otazníky, je text ztracen – viz co je mojibake.
Časté otázky
Jakou verzi PowerShellu mám?
Ukáže to $PSVersionTable.PSVersion. 5.1 je Windows PowerShell vestavěný ve Windows, od verze 7 se jmenuje jen PowerShell a ve výchozím stavu používá UTF-8.
Proč Excel otevírá můj CSV z PowerShellu špatně?
PowerShell 7 zapisuje UTF-8 bez BOM, který Excel nepozná. Použijte -Encoding utf8BOM nebo soubor uložte s BOM v Mojibusteru. Víc o Excelu a rozsypaném čaji v CSV.
Potřebuji chcp 65001?
Jen u programů, které se řídí kódovou stránkou konzole. Uvnitř PowerShellu stačí [Console]::OutputEncoding.