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.
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 UTF8lee bien los archivos UTF-8 incluso sin BOM.Set-Content,Out-FileyAdd-Contentescriben UTF-8 con-Encoding UTF8; en la 5.1 siempre con BOM.Export-Csv datos.csv -Encoding UTF8 -NoTypeInformationen 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.