Diferencias entre Windows PowerShell 5.1 y PowerShell 7 ── Guía práctica de migración de scripts internos

· Actualizado el: · · PowerShell, Windows, Migración, Automatización, Mejora operativa, Scripts, Aprovechamiento de activos existentes

«Si instalo PowerShell 7 en el servidor, ¿no se rompen los scripts que ya tengo funcionando?», «¿Es un problema seguir con la versión 5.1?» ── cada vez recibimos más consultas de este tipo de clientes con scripts operativos internos. PowerShell viene incluido de fábrica en Windows (la versión 5.1), mientras que PowerShell 7 se instala por separado. Como comparten nombre, es fácil pensar que «al actualizar la versión, una sustituye a la otra», pero en realidad son productos distintos que coexisten.

Si se introduce la versión 7 sin entender bien esta relación, se acaba tropezando con uno de estos dos problemas: «lo instalé pero no cambió nada (las tareas siguen ejecutándose con 5.1)», o, al contrario, «tras migrar, la integración de archivos en japonés terminó con caracteres corruptos». Este segundo caso es un incidente característico de los entornos en japonés, y su causa está en la diferencia de codificación de caracteres predeterminada.

Este artículo está dirigido al personal de sistemas y de operaciones que gestiona scripts internos. Explicamos, desde su funcionamiento interno, la relación y las diferencias entre 5.1 y 7, y resumimos el procedimiento real de migración junto con tablas de decisión.

1. Primero, la conclusión

  • Windows PowerShell 5.1 y PowerShell 7 son productos distintos que coexisten en paralelo (side by side). La versión 5.1 viene incluida con Windows y se basa en .NET Framework; la versión 7 se instala por separado y se construye sobre .NET. Instalar la versión 7 no elimina la 5.1.12
  • Microsoft ya no añade funciones nuevas a la versión 5.1. Su soporte está ligado al ciclo de vida del propio Windows, y el desarrollo se concentra en la versión 7. Los scripts nuevos deberían escribirse teniendo la versión 7 como referencia.13
  • El ejecutable es distinto. La versión 5.1 usa powershell.exe y la versión 7 usa pwsh.exe. Mientras no se reescriba el comando de inicio en el Programador de tareas y sitios similares, los mecanismos existentes seguirán ejecutándose con la versión 5.1.45
  • La codificación de caracteres predeterminada es distinta. En la versión 5.1 varía según el cmdlet (Out-File usa UTF-16LE, Get-Content usa ANSI, etc.), mientras que la versión 7 usa siempre UTF-8 sin BOM. Es la primera trampa con la que se tropieza al migrar en un entorno en japonés.6
  • Para los módulos que no funcionan en la versión 7 existe la función de compatibilidad de Windows. Con Import-Module -UseWindowsPowerShell se carga el módulo en un proceso de 5.1 en segundo plano y se usa a través de remoting, pero lo que se devuelve son objetos serializados en los que no se pueden invocar métodos.7
  • Con #Requires -Version y $PSVersionTable se deja explícito en el propio código «con cuál versión debe ejecutarse el script». Esto permite detener, antes de la ejecución, el incidente de que un script se ejecute con una versión no prevista y falle silenciosamente.89
  • La migración se realiza por etapas: inventario → prueba de ejecución con la versión 7 → actualización del comando de inicio. La versión 7 se instala mediante MSI o winget, y conviene decidir desde el principio también cómo se distribuirán las actualizaciones (por ejemplo, a través de Microsoft Update).524

2. ¿Qué relación hay entre 5.1 y 7? ── Coexistencia, no sustitución

Primero, veamos el panorama general en una tabla.

Aspecto Windows PowerShell 5.1 PowerShell 7
Forma de obtenerlo Incluido con Windows1 Instalación aparte (MSI/winget, etc.)2
Base .NET Framework 4.x5 .NET (7.4 usa .NET 8.0, por ejemplo)54
Ejecutable powershell.exe pwsh.exe4
Directorio de instalación $Env:windir\System32\WindowsPowerShell\v1.05 $Env:ProgramFiles\PowerShell\75
Desarrollo futuro Sin adición de funciones nuevas1 Eje del desarrollo. Tiene versiones LTS y Stable3
Periodo de soporte Sigue el ciclo de vida del propio Windows3 Sigue la política de soporte del .NET base3

La versión 7 no sustituye a la 5.1: se instala en un directorio distinto y funciona en paralelo (side by side). El lugar donde se guardan los módulos (PSModulePath), el perfil y el registro de eventos se gestionan por separado, y como la PSModulePath de la versión 7 incluye también las rutas de módulos de la versión 5.1, desde la versión 7 se pueden cargar muchos de los módulos existentes.52

Con estas dos líneas puede comprobar en cualquier momento «en cuál de las dos versiones está». $PSVersionTable es una variable automática que contiene la información de versión de PowerShell.9

# Comprobar en cuál de las dos versiones de PowerShell se está
$PSVersionTable.PSVersion   # 5.1.x = Windows PowerShell, 7.x = PowerShell 7
$PSVersionTable.PSEdition   # Desktop = Windows PowerShell / Core = PowerShell 7

La postura oficial también es clara. Windows PowerShell es la versión incluida con Windows, Microsoft no la actualiza con funciones nuevas, y su soporte está ligado a la versión de Windows en uso. PowerShell (la serie 7), en cambio, se construye sobre un .NET más reciente, y para cada versión se fija un periodo de soporte alineado con la política de soporte del .NET base.13 La versión 5.1 no va a desaparecer mañana, pero la conclusión práctica es que «lo que se escriba de ahora en adelante» y «lo que se vaya a usar durante mucho tiempo» debería tener como referencia la versión 7.

3. La primera trampa ── diferencias en la codificación predeterminada y caracteres corruptos

El problema más frecuente al migrar en entornos en japonés son los caracteres corruptos (mojibake). La causa es clara: la codificación de caracteres predeterminada es distinta entre ambas versiones.6

Operación Predeterminado en 5.1 Predeterminado en 7
Out-File y redirección (>) UTF-16LE (con BOM)6 UTF-8 sin BOM6
Set-Content / Add-Content ANSI (Shift_JIS en entornos en japonés)6 UTF-8 sin BOM
Get-Content (archivo sin BOM) ANSI6 UTF-8 sin BOM
Export-Csv ASCII (se pierden los caracteres japoneses)6 UTF-8 sin BOM
Interpretación del propio script (sin BOM) Página de códigos ANSI6 UTF-8
# Aunque sea la misma línea, 5.1 y 7 generan archivos con secuencias de bytes distintas
'Hola' | Out-File -FilePath C:\temp\hello.txt
# Ejecutado en 5.1 → archivo UTF-16LE (con BOM)
# Ejecutado en 7   → archivo UTF-8 sin BOM

Esto tiene dos implicaciones prácticas.

En primer lugar, las integraciones de archivos que dan por hecho Shift_JIS pueden corromperse tanto al leer como al escribir en el momento mismo de pasar a la versión 7. Esto se debe a que Get-Content en la versión 5.1 lee los archivos sin BOM como ANSI (Shift_JIS en entornos en japonés), mientras que la versión 7 los lee como UTF-8. La solución es indicar explícitamente -Encoding en toda entrada y salida de archivos. En la versión 7 se puede especificar mediante el número de página de códigos (-Encoding 932) o mediante el nombre registrado, y desde la versión 7.4 también puede usarse el valor ansi.6 Puede encontrar la forma concreta de escribirlo para el procesamiento de CSV en el artículo publicado junto con este, «Automatizar el procesamiento de Excel y CSV con PowerShell».

En segundo lugar, el formato de guardado del propio archivo de script. Si la versión 5.1 lee un script con comentarios en japonés guardado en UTF-8 sin BOM, lo interpreta erróneamente como ANSI y produce caracteres corruptos o errores de sintaxis. Tal como recomienda la documentación oficial, si los scripts que contienen caracteres no ASCII se guardan en UTF-8 con BOM, se interpretan correctamente tanto en la versión 5.1 como en la 7.6

4. Compatibilidad ── qué deja de funcionar y el alcance real de la función de compatibilidad de Windows

4.1. Qué deja de funcionar

La versión 7 puede cargar tal cual muchos de los módulos existentes5, pero hay algunos que no. Estos son los ejemplos representativos que menciona la documentación oficial.

  • Módulos que dejaron de incluirse: la versión 7 no incluye módulos como PSWorkflow/PSWorkflowUtility (flujos de trabajo), PSScheduledJob, los módulos para ISE, ni Microsoft.PowerShell.LocalAccounts.4
  • Snap-ins: los snap-ins, el formato de extensión antiguo anterior a los módulos, no son compatibles con la versión 7.4
  • Código muy ligado a .NET Framework: como la versión 7 tiene un .NET base distinto, los scripts que invocan directamente métodos de .NET pueden cambiar de comportamiento.54
  • Cambios sutiles de comportamiento: Export-Csv ya no genera la línea #TYPE de forma predeterminada, Group-Object ahora devuelve los grupos ordenados, y hay otros cambios de este tipo que afectan a los scripts que dependen de la salida.4

También existe incompatibilidad en el sentido contrario. Los scripts que usan sintaxis o funciones añadidas en la versión 7, como el operador ternario o ForEach-Object -Parallel, no funcionan en la versión 5.1.5 Es decir, para cada script hay que decidir si «escribirlo para que funcione en ambas versiones» o «dejar explícito con cuál de las dos debe ejecutarse».

Puede consultar el estado de compatibilidad de los módulos de Microsoft en la página oficial de compatibilidad de módulos.10

Conviene decidir también, al mismo tiempo, hacia dónde migrar el entorno de edición (ISE). No está previsto eliminar Windows PowerShell ISE de Windows, y seguirá recibiendo correcciones de seguridad y de alta prioridad, pero el desarrollo de funciones nuevas ha terminado, y solo es compatible con PowerShell 5.1 o anterior.11 Es decir, no tiene sentido escribir y ejecutar en ISE los scripts que se van a ejecutar con la versión 7. El destino de migración que recomienda oficialmente es Visual Studio Code con la extensión de PowerShell: al instalar la extensión se puede cambiar la versión de PowerShell que usa la consola integrada (también se pueden añadir rutas adicionales en la configuración). Para quienes están acostumbrados a ISE también hay preparada una guía para «reproducir en VS Code la sensación de uso de ISE», así que lo más rápido es empezar el cambio desde ahí.11 En los departamentos de sistemas suele haber muchos usuarios de ISE, así que anuncie el plan de migración de scripts y el cambio de entorno de edición al mismo tiempo.

4.2. Cómo funciona y qué limitaciones tiene la función de compatibilidad de Windows (-UseWindowsPowerShell)

La versión 7 cuenta con la función de compatibilidad de Windows para los módulos que solo funcionan con la versión 5.1.

# Cargar, a través de la función de compatibilidad, un módulo no compatible con 7 (ejemplo de la documentación oficial)
Import-Module -Name ScheduledTasks -UseWindowsPowerShell

El mecanismo es una aplicación de remoting. En segundo plano se inicia un proceso de Windows PowerShell 5.1, el módulo se carga en una sesión llamada WinPSCompatSession, y en el lado de la versión 7 se importa un módulo proxy generado mediante remoting implícito. Los módulos exclusivos de la versión 5.1 que están bajo System32 también se cargan implícitamente mediante este mecanismo, tanto al especificarlos por nombre como al detectarlos automáticamente por comando.7

Al representarlo en un diagrama, la relación entre los dos procesos queda clara.

powershell.exe ── proceso de 5.1 iniciado en segundo planopwsh.exe ── proceso de PowerShell 7Reenvía la invocación del comandoResultadoSolo vuelve una copia serializada del valorNo se pueden invocar métodosWinPSCompatSessionTodos los módulos cargados mediante la funciónde compatibilidad comparten un mismo runspaceMódulo real que solo funciona con 5.1Script principalMódulo proxyEntrada generada mediante remoting implícito.No es el módulo real

Como muestra el diagrama, en el lado de la versión 7 solo hay la entrada, no el módulo real. La realidad no es «si instalo la versión 7, todo funciona con la versión 7», sino «la versión 7 le pide el trabajo a la versión 5.1 y recibe una copia del resultado», y todas las limitaciones que se explican a continuación se derivan de esta estructura.

Es útil, pero si se usa sin entender sus limitaciones, se rompe silenciosamente. Estas son las limitaciones que documenta oficialmente:7

  • Lo que se intercambia son valores serializados, no objetos en bruto. No se pueden invocar métodos sobre el objeto recibido; solo llega una instantánea de sus propiedades.
  • Solo funciona en un Windows local y requiere Windows PowerShell 5.1.
  • Todos los módulos cargados mediante la función de compatibilidad comparten un mismo runspace (un único proceso de 5.1).
  • Algunos módulos (como PSScheduledJob) se rechazan de forma predeterminada.

Procesos como «invocar un método sobre el resultado obtenido» o «necesitar el objeto en bruto a mitad de la canalización» no funcionan con la función de compatibilidad. En esos casos también se puede escribir el código de forma que toda la canalización se ejecute en el lado de la versión 5.1 y solo se reciba el resultado final7, pero si eso complica demasiado el código, la experiencia práctica dice que resulta más fácil de mantener dejar solo ese proceso funcionando con la versión 5.1.

5. Escribir de forma defensiva ── #Requires y bifurcación por versión

Durante el periodo de migración, inevitablemente habrá momentos en los que «no se sepa con cuál versión se va a ejecutar» un script. Lo peor que puede pasar es que se ejecute con una versión no prevista y falle a mitad de camino, así que conviene incorporar protecciones en el propio script.

Si se escribe una declaración #Requires, el script se rechaza antes de ejecutarse en cualquier versión de PowerShell que no cumpla la condición indicada.8

#Requires -Version 7.0
# Este script es exclusivo de la versión 7 (usa ForEach-Object -Parallel, entre otras cosas).
# Si se inicia con powershell.exe (5.1), no se ejecuta nada a partir de aquí

Por el contrario, en los scripts exclusivos de la versión 5.1 se escribe #Requires -PSEdition Desktop. Desktop es el nombre de la edición de la serie 5.1, y Core el de la serie 7.89

Si se trata de un script que funciona con ambas versiones pero se quiere cambiar el comportamiento solo en una parte, se bifurca en tiempo de ejecución con $PSVersionTable.9

# En un script compatible con 5.1 y 7, bifurcar solo el procesamiento donde hay diferencia de versión
if ($PSVersionTable.PSVersion.Major -ge 6) {
    $enc = 932            # 7: se puede indicar Shift_JIS mediante el número de página de códigos
} else {
    $enc = 'Default'      # 5.1: Default = página de códigos ANSI del sistema
}
Get-Content -LiteralPath $path -Encoding $enc

La clave es incorporar esta indicación explícita «en el momento del inventario», no «después de terminar la migración». Con una sola línea de #Requires, cualquiera puede saber a cuál de los dos mundos pertenece el script.

6. Cómo llevar a cabo la migración ── del inventario a la actualización del Programador de tareas

La migración real se lleva a cabo en el siguiente orden. Un cambio general de una sola vez es fuente de incidentes, así que el principio es migrar por etapas.

Paso 1: inventario. Se identifican, en los repositorios de scripts y en el Programador de tareas, los archivos .ps1 que están en uso y sus comandos de inicio.

# Identificar en el Programador de tareas las tareas que inician PowerShell
Get-ScheduledTask | ForEach-Object {
    foreach ($action in $_.Actions) {
        # Se revisan tanto el ejecutable como los argumentos para detectar también inicios indirectos como cmd.exe /c powershell ...
        if ("$($action.Execute) $($action.Arguments)" -match 'powershell|pwsh') {
            [pscustomobject]@{
                TaskPath  = $_.TaskPath        # El nombre de la tarea solo es único dentro de su carpeta, por eso se guarda también la ruta
                TaskName  = $_.TaskName
                Execute   = $action.Execute    # powershell.exe o pwsh.exe
                Arguments = $action.Arguments
            }
        }
    }
} | Export-Csv -Path .\ps-tasks.csv -NoTypeInformation -Encoding UTF8

El archivo ps-tasks.csv resultante tiene 4 columnas. A continuación se indica el significado de cada columna y un ejemplo de su formato (los valores son solo ejemplos de formato; el contenido real varía según el entorno).

Columna Contenido Ejemplo de valor
TaskPath Carpeta de la tarea. El nombre de la tarea solo es único dentro de su carpeta \ o \Contoso\Batch\
TaskName Nombre de la tarea DailyReport
Execute Ejecutable que se inicia powershell.exe / C:\Program Files\PowerShell\7\pwsh.exe / cmd.exe
Arguments Cadena de argumentos -NoProfile -ExecutionPolicy RemoteSigned -File C:\scripts\daily-report.ps1

Este CSV se elabora para revisar tres puntos. Las filas donde Execute es powershell.exe son tareas que todavía se ejecutan con la versión 5.1, es decir, objeto de migración. Las filas donde Execute es cmd.exe tienen el inicio de PowerShell incrustado dentro de Arguments, así que hay que abrir el contenido y revisarlo. Y las filas donde ni -File ni -Command aparecen en Arguments son llamadas que pasan los valores por posición, por lo que su interpretación cambiará al sustituirlas por pwsh en el paso 5 (el motivo se explica en el paso 5). Con solo clasificar estos tres casos queda definido el denominador del plan de migración.

Paso 2: instalación de la versión 7. Se instala mediante el paquete MSI (adecuado para su distribución con herramientas de gestión) o con winget.52

Qué versión instalar y cómo se decide con la siguiente guía orientativa.32

Punto Opciones Guía de decisión
Qué versión LTS / Stable Para servidores de producción, LTS. LTS es la versión que corresponde a la LTS de .NET; sus actualizaciones se limitan a correcciones de seguridad importantes y mantenimiento, y está diseñada para minimizar el impacto sobre las cargas de trabajo existentes. Stable incluye funciones nuevas, pero su soporte termina unos 6 meses después de salir la siguiente LTS3
Equipos cliente winget Es el método que la documentación oficial recomienda para clientes Windows2
Servidores y despliegue masivo Paquete MSI Se indica expresamente que es el más adecuado para Windows Server y el despliegue empresarial. Incluso se puede especificar la vía de actualización mediante propiedades de línea de comandos2
Versión MSIX (tienda) Precaución Es una instalación por usuario, no se puede aplicar a todos los usuarios, y por el sandbox de la aplicación tiene restricciones como no poder usar PowerShell Remoting a través de WSMan. No es adecuada para servidores2
# Instalación con winget. Las actualizaciones también siguen la misma vía con winget upgrade
winget install --id Microsoft.PowerShell --source winget

# Si se desea instalar mediante el paquete MSI (para servidores y herramientas de gestión de distribución)
winget install --id Microsoft.PowerShell --source winget --installer-type wix

El propio winget tiene sus condiciones. A partir del paquete winget 7.6.0, winget install --id Microsoft.PowerShell cambió su comportamiento y ahora instala de forma predeterminada el paquete MSIX, así que si se quiere el MSI hay que añadir --installer-type wix como se muestra arriba. Además, winget no se puede usar en Windows Server 2022 o anterior (viene incluido en la versión Desktop Experience de Windows Server 2025). Lo más prudente es planificar el despliegue en grupos de servidores partiendo del MSI.2

Conviene decidir desde el principio también la operativa de actualizaciones. El MSI de la versión 7.2 en adelante tiene una opción (activada de forma predeterminada) para recibir actualizaciones a través de Microsoft Update, que se puede integrar en el flujo habitual de actualizaciones de WSUS o de las herramientas de gestión de configuración.4 El peor escenario es dejar instalaciones sin gestionar que se quedan con una versión 7 antigua para siempre.

Paso 3: prueba de ejecución con la versión 7. Se ejecuta cada script inventariado con pwsh y se comprueba si funciona y si los archivos de salida no tienen caracteres corruptos. Como la versión 7 coexiste con la 5.1, poder probar sin detener las tareas de producción es una ventaja del diseño side by side.2 Si aparece un error, se aísla el problema de compatibilidad del capítulo 4 (módulos, API de .NET, cambios de comportamiento).

Si no se define de antemano el criterio de «funcionó», la prueba nunca termina, así que conviene tener las condiciones de aprobación en una lista de comprobación.

  • pwsh -NoProfile -File <script> se ejecuta hasta el final y $LASTEXITCODE termina en 0
  • No aparece nada en el flujo de errores (las advertencias previstas se aceptan tras revisar su contenido)
  • Todos los módulos de los que depende se cargan en la versión 7 (Import-Module funciona; también se comprueba si no está cayendo en la función de compatibilidad)
  • El contenido del archivo de salida coincide con el de la versión 5.1 (Compare-Object, más abajo)
  • La codificación del archivo de salida es la que espera el sistema receptor (capítulo 3; imprescindible si hay algún destino que dé por hecho Shift_JIS)
  • En los procesos que modifican datos se ha confirmado con -WhatIf que el objetivo es el mismo que con 5.1
  • El tiempo de ejecución no se ha alargado de forma extrema (puede ralentizarse si pasa por la función de compatibilidad)

Para contrastar la salida, lo más fiable es ejecutar el mismo script tanto en la versión 5.1 como en la 7 y comparar las diferencias.

# Ejecutar el mismo script en 5.1 y en 7, y comparar los archivos de salida
& "$Env:windir\System32\WindowsPowerShell\v1.0\powershell.exe" -NoProfile -File .\daily-report.ps1
Move-Item .\report.csv .\report-51.csv -Force
& "$Env:ProgramFiles\PowerShell\7\pwsh.exe" -NoProfile -File .\daily-report.ps1
Move-Item .\report.csv .\report-7.csv -Force

# Diferencia línea por línea. Si hay alguna columna que cambia cada vez, como la fecha de ejecución, excluirla antes de comparar
Compare-Object (Get-Content .\report-51.csv) (Get-Content .\report-7.csv)

# Comprobar incluso si coinciden a nivel de bytes (aquí aparecen las diferencias de BOM o de salto de línea)
(Get-FileHash .\report-51.csv).Hash -eq (Get-FileHash .\report-7.csv).Hash

Cuando aparezca una diferencia, primero hay que distinguir si «el valor es distinto» o si «visualmente es igual pero solo difiere la secuencia de bytes». Si Compare-Object no muestra diferencias pero Get-FileHash sí, la causa es una diferencia de codificación o de salto de línea (capítulo 3). Defina la migración como completada no cuando «termine sin excepciones en la versión 7», sino cuando «se obtenga el mismo resultado que con la versión 5.1».

Paso 4: dejar explícito con cuál versión se debe ejecutar. A los que superaron la prueba se les añade #Requires -Version 7.0, y a los que se quedan en la versión 5.1, #Requires -PSEdition Desktop (capítulo 5).

Paso 5: actualización del comando de inicio. Se reescribe la acción del Programador de tareas. Si se olvida este paso, ocurre que «se creía haber migrado a la versión 7, pero en realidad sigue ejecutándose con la 5.1».

# Antes del cambio (se ejecuta con 5.1):
#   powershell.exe -NoProfile -ExecutionPolicy RemoteSigned -File C:\scripts\daily-report.ps1
# Después del cambio (se ejecuta con 7):
#   "C:\Program Files\PowerShell\7\pwsh.exe" -NoProfile -File C:\scripts\daily-report.ps1

Además, en pwsh.exe el primer parámetro posicional cambió de -Command a -File. Si se sustituye mecánicamente una llamada equivalente a powershell.exe -Command "...", la interpretación cambia, así que indique siempre explícitamente -File o -Command.4

Para el tratamiento de la directiva de ejecución y la firma de scripts, consulte el artículo publicado junto con este, «Directiva de ejecución de PowerShell y firma de scripts»; para decidir la migración desde archivos por lotes (.bat), consulte «¿Conviene migrar los archivos por lotes a PowerShell?».

7. Reglas prácticas habituales (tabla de decisión)

Punto Opciones Guía de decisión
Referencia para scripts nuevos 5.1 / 7 En principio, 7. La versión 5.1 se mantiene sin añadir funciones nuevas, y el eje del desarrollo es la 713
Migración de scripts existentes Cambio general de una vez / Migración por etapas Inventario → prueba en 7 → actualización del comando de inicio a partir de los que la superen. Es posible migrar por etapas gracias al diseño side by side5
Hay módulos exclusivos de 5.1 Renunciar a migrar / -UseWindowsPowerShell / Dejar solo ese proceso en 5.1 Usar la función de compatibilidad entendiendo su limitación de serialización (no se pueden invocar métodos). Si se complica demasiado, es más fácil de mantener dejarlo en 5.17
Indicación explícita de versión No hacer nada / #Requires Incorporar #Requires o una comprobación en tiempo de ejecución en todos los scripts. Detiene antes de la ejecución el uso con una versión no prevista8
Entrada/salida de archivos Dejarlo en los valores predeterminados / -Encoding explícito Indicarlo siempre. Evita de forma estructural los caracteres corruptos causados por la diferencia entre los valores predeterminados de 5.1 y 76
Operativa de actualización de 7 Reinstalar manualmente / Integración del MSI con Microsoft Update, o winget Decidir primero la vía de actualización y luego distribuir. Lo más peligroso es una versión 7 antigua abandonada42

8. Resumen

  • La versión 5.1 y la 7 son productos distintos que coexisten en paralelo. Instalar la versión 7 no rompe los mecanismos existentes, pero, al contrario, mientras no se cambie el comando de inicio, no se migra nada.
  • La versión 5.1 está en modo de mantenimiento: sin funciones nuevas y con el soporte ligado al propio Windows; el eje del desarrollo es la versión 7. Los scripts nuevos se escriben teniendo la versión 7 como referencia.
  • La mayor trampa en entornos en japonés es la diferencia de codificación predeterminada (variable en 5.1, UTF-8 sin BOM en 7). Se evita indicando explícitamente -Encoding en la entrada/salida y guardando los scripts en UTF-8 con BOM.
  • Los módulos que no funcionan en la versión 7 se pueden salvar con la función de compatibilidad de Windows, pero tiene la limitación de que solo devuelve valores serializados. Si no es viable, se deja solo ese proceso funcionando con la versión 5.1.
  • Con #Requires y $PSVersionTable se deja explícito en el código «con cuál versión debe ejecutarse el script», y se detiene la ejecución con una versión no prevista.
  • La migración avanza por etapas: inventario → instalación de la versión 7 (MSI/winget) → prueba de ejecución → adición de #Requires → actualización del comando de inicio en el Programador de tareas.

Artículos relacionados

Áreas de consultoría relacionadas

KomuraSoft LLC se encarga del inventario de los activos de scripts internos y de la planificación y ejecución de la migración por etapas a PowerShell 7, del aislamiento de los procesos que dependen de módulos exclusivos de 5.1, y de la investigación de incidencias del tipo «tras migrar aparecieron caracteres corruptos» o «dejó de funcionar».

Referencias

  1. Microsoft Learn, What is Windows PowerShell?. Sobre que Windows PowerShell y PowerShell son productos distintos, que Windows PowerShell viene incluido con Windows y se construye sobre .NET Framework, siendo 5.1 su última versión, y que Microsoft no lo actualiza con funciones nuevas, con un soporte ligado a la versión de Windows en uso.  2 3 4 5 6

  2. Microsoft Learn, Install PowerShell 7 on Windows. Sobre que PowerShell 7 no sustituye a Windows PowerShell 5.1 y se instala en un directorio nuevo, ejecutándose side by side; que el directorio de instalación predeterminado es $Env:ProgramFiles\PowerShell\7; y los métodos de instalación como winget o MSI.  2 3 4 5 6 7 8 9 10 11 12

  3. Microsoft Learn, PowerShell Support Lifecycle. Sobre que PowerShell 7 tiene las categorías de lanzamiento LTS y Stable, y que su fecha de fin de soporte sigue la política de soporte del .NET base; y que Windows PowerShell, como componente de Windows, sigue el ciclo de vida de soporte de Windows.  2 3 4 5 6 7 8

  4. Microsoft Learn, Differences between Windows PowerShell 5.1 and PowerShell 7.x. Sobre que el nombre del ejecutable cambió de powershell.exe a pwsh.exe, lo que sustenta la coexistencia side by side; que el primer parámetro posicional cambió de -Command a -File; que módulos como PSWorkflow, PSScheduledJob y LocalAccounts, así como los snap-ins, no están incluidos en la versión 7; los cambios de comportamiento como la omisión predeterminada de la línea #TYPE en Export-Csv o la salida ordenada de Group-Object; el .NET base de cada versión; y la opción de integración con Microsoft Update del MSI desde la versión 7.2.  2 3 4 5 6 7 8 9 10 11

  5. Microsoft Learn, Migrating from Windows PowerShell 5.1 to PowerShell 7. Sobre que PowerShell 7 está diseñado partiendo de su coexistencia side by side con la versión 5.1 (ruta de instalación, PSModulePath, perfil y registro de eventos independientes); las rutas de instalación de la 5.1 y de la 7; que muchos módulos existentes funcionan en la versión 7 y que UseWindowsPowerShell complementa la compatibilidad; funciones nuevas como el operador ternario o ForEach-Object -Parallel; y el despliegue mediante MSI/ZIP.  2 3 4 5 6 7 8 9 10 11 12

  6. Microsoft Learn, about_Character_Encoding. Sobre que la codificación predeterminada de Windows PowerShell 5.1 no es coherente entre cmdlets (Out-File y la redirección usan UTF-16LE, Set-Content/Get-Content usan ANSI, Export-Csv usa ASCII, etc.); que PowerShell 6 en adelante usa siempre UTF-8 sin BOM de forma predeterminada; que la versión 5.1 interpreta erróneamente como ANSI los scripts sin BOM, por lo que los scripts con caracteres no ASCII deben guardarse en UTF-8 con BOM; y sobre la especificación por número de página de códigos y el valor ansi de la versión 7.4.  2 3 4 5 6 7 8 9 10 11

  7. Microsoft Learn, about_Windows_PowerShell_Compatibility. Sobre que la función de compatibilidad carga el módulo en un proceso de Windows PowerShell 5.1 en segundo plano (WinPSCompatSession) y genera un módulo proxy mediante remoting implícito; que existe tanto la carga explícita mediante UseWindowsPowerShell como la carga automática; y las limitaciones de que funciona con valores serializados y no con objetos en bruto, de que está limitada a Windows local, de que comparte un único runspace y de que tiene una lista de módulos rechazados de forma predeterminada.  2 3 4 5

  8. Microsoft Learn, about_Requires. Sobre que la declaración #Requires rechaza la ejecución misma del script mientras no se cumplan condiciones previas como la versión de PowerShell indicada (-Version), la edición (-PSEdition Core o Desktop) o los módulos requeridos.  2 3 4

  9. Microsoft Learn, about_Automatic_Variables. Sobre que $PSVersionTable es una tabla hash de solo lectura que contiene los detalles de la versión de PowerShell de la sesión actual, y que la propiedad PSEdition toma el valor Desktop en la versión 5.1 (Windows con todas las funciones) y Core desde la versión 6 en adelante.  2 3 4

  10. Microsoft Learn, PowerShell 7 module compatibility. Sobre que se recopila el estado de compatibilidad con PowerShell 7 de cada módulo de Microsoft (incluidos los módulos de administración de Windows). 

  11. Microsoft Learn, Using Visual Studio Code for PowerShell Development. Sobre que Windows PowerShell ISE permanece en Windows pero su desarrollo de funciones nuevas ha terminado y solo funciona con PowerShell 5.1 o anterior; que no está prevista su eliminación de Windows y seguirá recibiendo correcciones de seguridad y de alta prioridad; que para el desarrollo en PowerShell se usa Visual Studio Code con la extensión de PowerShell; que en el menú de sesión se puede cambiar la versión de PowerShell utilizada y añadir rutas adicionales en la configuración; y que hay preparada una guía para reproducir en VS Code la sensación de uso de ISE.  2

Artículos recientes con las mismas etiquetas para profundizar en temas cercanos.

Estas páginas sitúan el tema en un contexto más amplio de servicios y decisiones.

El artículo está directamente relacionado con los siguientes servicios.

Preguntas frecuentes

Preguntas habituales en las consultas sobre el tema del artículo.

¿Qué diferencia hay entre Windows PowerShell 5.1 y PowerShell 7?
Son productos distintos. La versión 5.1 viene incluida con Windows, se ejecuta sobre .NET Framework, Microsoft ya no le añade funciones nuevas y su soporte sigue el ciclo de vida del propio Windows. PowerShell 7 se ejecuta sobre .NET (antes .NET Core), es un producto de instalación independiente y es donde se concentra el desarrollo actual. La versión 7 no sustituye a la 5.1, sino que se instala en un directorio distinto y coexiste en paralelo (side by side); incluso el nombre del ejecutable las distingue: powershell.exe y pwsh.exe respectivamente.
¿Instalar PowerShell 7 rompe los scripts existentes de 5.1?
No se rompen. La versión 7 se instala en un directorio distinto (de forma predeterminada, Program Files\PowerShell\7), y tanto el lugar donde se guardan los módulos como el perfil se gestionan por separado de la versión 5.1. Los mecanismos existentes que inician powershell.exe, como los del Programador de tareas, seguirán funcionando con 5.1 exactamente igual que antes. Precisamente por eso hay que tener cuidado con lo contrario: «instalar la versión 7 por sí solo no migra nada», y para que un script se ejecute con la versión 7 hay que cambiar explícitamente el comando de inicio a pwsh.exe.
¿Por qué los scripts que ya tenía se ven con caracteres corruptos en PowerShell 7?
Porque cambió la codificación de caracteres predeterminada. En la versión 5.1 el valor predeterminado varía según el cmdlet (Out-File usa UTF-16LE, Get-Content usa ANSI, etc.), mientras que en la versión 7 es siempre UTF-8 sin BOM. En entornos en japonés, donde muchas integraciones de archivos dan por hecho Shift_JIS, migrar sin tocar los valores predeterminados puede corromper caracteres tanto al leer como al escribir. Esto se evita casi por completo con dos medidas: indicar explícitamente el parámetro -Encoding en toda entrada y salida de archivos, y guardar en UTF-8 con BOM los scripts que contengan caracteres no ASCII.
¿Qué hacer con los módulos que no funcionan en PowerShell 7?
Primero compruebe si funciona con un Import-Module normal en la versión 7. Si no funciona, puede usar la función de compatibilidad de Windows (Import-Module -UseWindowsPowerShell), que carga el módulo en un proceso de 5.1 que se ejecuta en segundo plano y lo pone a disposición de la versión 7 mediante remoting. Sin embargo, tiene limitaciones: lo que se recibe son objetos serializados en los que no se pueden invocar métodos, y solo funciona en Windows local. Para los procesos que chocan con estas limitaciones, lo más realista es no forzar la migración y dejar esa parte concreta funcionando con la versión 5.1.
¿Cómo se debe llevar a cabo la migración de scripts internos de 5.1 a 7?
En lugar de un cambio general de una sola vez, conviene hacer una migración por etapas. Primero se hace un inventario de los archivos .ps1 del Programador de tareas y de los repositorios de scripts, y se prueba cada uno ejecutándolo con la versión 7 (pwsh) para comprobar si funciona. A los que funcionen se les añade #Requires -Version 7, y se actualiza el comando de inicio del Programador de tareas de powershell.exe a pwsh.exe. Los que solo funcionan con 5.1 no se fuerzan a migrar: se dejan tal cual, dejando explícito con cuál de las dos versiones deben ejecutarse. La propia versión 7 se instala mediante MSI o winget, y conviene decidir también, desde el principio, el método de distribución de las actualizaciones.

Perfil del autor

Página de presentación del autor del artículo.

Go Komura

Representante de KomuraSoft LLC

Especializado en desarrollo de software para Windows, consultoría técnica e investigación de fallos, sobre todo en proyectos con sistemas existentes y errores difíciles de reproducir.

Volver al blog