Arreglar la codificación de caracteres en PowerShell

¿Tu script escribe ñ o ? en vez de ñ, o la consola muestra texto raro? Windows PowerShell 5.1 usa una codificación distinta según el comando. Aquí tienes las causas y los parámetros correctos; los archivos ya rotos los reparas arriba, en el navegador.

Funciona con texto y con estos archivos:

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

Por ejemplo exportaciones de Excel, copias de bases de datos, subtítulos o código web.

Reparar

  1. Suelta un archivo o pega texto
  2. Se repara automáticamente
  3. Copia o descarga
o simplemente arrastra un archivo aquí

El problema de fondo: cada comando, una codificación

En Windows PowerShell 5.1 casi cada comando tiene su propia codificación predeterminada: Get-Content lee los archivos sin BOM como ANSI (Windows-1252), Out-File y > escriben UTF-16, Set-Content escribe ANSI y Export-Csv ASCII. PowerShell 7 lo unificó y usa UTF-8 sin BOM en todas partes.

Un archivo UTF-8 leído con Get-Content en PowerShell 5.1

Antes

Usuario;Departamento;Oficina
José Muñoz;Ventas;Málaga
Anaïs Pérez;Compras;Peñíscola

Después

Usuario;Departamento;Oficina
José Muñoz;Ventas;Málaga
Anaïs Pérez;Compras;Peñíscola

Leer y escribir archivos correctamente

  • Get-Content datos.csv -Encoding UTF8 lee bien los archivos UTF-8 incluso sin BOM.
  • Set-Content, Out-File y Add-Content escriben UTF-8 con -Encoding UTF8; en la 5.1 siempre con BOM.
  • Export-Csv datos.csv -Encoding UTF8 -NoTypeInformation en vez del ASCII predeterminado, que cambia las letras con tilde por ?.
  • Para todos los comandos a la vez: $PSDefaultParameterValues['*:Encoding'] = 'utf8' al principio del script.

Peticiones web con Invoke-RestMethod e Invoke-WebRequest

Si un servidor no indica el juego de caracteres en su Content-Type, Windows PowerShell 5.1 decodifica la respuesta como ISO-8859-1. Las respuestas UTF-8 contienen entonces ñ. La solución: obtén la respuesta como bytes y decodifícala tú, por ejemplo con [Text.Encoding]::UTF8.GetString((Invoke-WebRequest $url).RawContentStream.ToArray()).

Scripts con caracteres especiales

Si guardas un script como UTF-8 sin BOM, Windows PowerShell 5.1 lo lee como ANSI. Los caracteres de cadenas como Write-Host "Cañón" salen entonces como Cañón. Guarda los .ps1 como UTF-8 con BOM: en VS Code, con la codificación de la barra de estado; en Notepad++, en el menú de codificación con la opción UTF-8-BOM.

La consola

Si solo la ventana de la consola muestra caracteres raros como ├▒ en vez de ñ, el archivo suele estar bien: la consola lee UTF-8 como página de códigos DOS 437 (más sobre este patrón). Cambia la salida con [Console]::OutputEncoding = [Text.Encoding]::UTF8. Para lo que envías a programas externos, define también $OutputEncoding = [Text.Encoding]::UTF8.

Si el archivo ya se escribió roto, suéltalo en el cuadro de arriba: Mojibuster repara ñ y compañía y convierte los archivos ANSI a UTF-8. Si el archivo ya contiene signos de interrogación, el texto se perdió; mira signos de interrogación en vez de acentos.

Preguntas frecuentes

¿Qué versión de PowerShell tengo?

$PSVersionTable.PSVersion te lo dice. La 5.1 es el Windows PowerShell integrado en Windows; desde la 7 se llama solo PowerShell y usa UTF-8 por defecto.

¿Por qué Excel abre mal mi CSV de PowerShell?

PowerShell 7 escribe UTF-8 sin BOM y Excel no lo reconoce. Usa -Encoding utf8BOM o guarda el archivo con BOM en Mojibuster. Más sobre Excel con caracteres raros.

¿Necesito chcp 65001?

Solo para programas que siguen la página de códigos de la consola. Dentro de PowerShell basta con [Console]::OutputEncoding.

Más guías