Establecer la Directiva de Ejecución para gestionar las Directivas de Ejecución de PowerShell

¿Alguna vez has descargado un script de PowerShell, lo has ejecutado y te has encontrado con el famoso mensaje de error a continuación? Si es así, necesitas el cmdlet Set-ExecutionPolicy y este tutorial!

PowerShell Script Execution Disabled Error

En esta publicación, aprenderás sobre las políticas de ejecución de PowerShell y cómo gestionarlas con el cmdlet Set-ExecutionPolicy. ¡Al final de esta publicación, no solo sabrás cómo ejecutar scripts, sino también cómo utilizar las políticas de ejecución!

Este tutorial fue escrito teniendo en cuenta Windows PowerShell, y todas las demostraciones se realizaron con Windows PowerShell. Las políticas de ejecución no son exclusivas de Windows PowerShell y funcionan de manera muy similar en PowerShell 6+. Sin embargo, si estás trabajando con PowerShell 6+, es posible que encuentres pequeñas diferencias en el comportamiento.

¿Qué es una Política de Ejecución?

Si alguna vez te has encontrado con el error descrito anteriormente, has encontrado una política de ejecución. Las políticas de ejecución de PowerShell son un mecanismo de seguridad para proteger tu sistema contra la ejecución de scripts maliciosos. Las políticas de ejecución no te impiden ejecutar código de PowerShell en la consola como shell, pero sí la ejecución de scripts.

Microsoft dice que una política de ejecución no es técnicamente una medida de “seguridad”, sino más bien una puerta que puedes abrir y cerrar. Después de todo, puedes pasar fácilmente por alto una política de ejecución definida, como aprenderás más adelante.

Las políticas de ejecución se basan en la confianza. Si confías en un script, es probable que no sea malicioso. Las políticas de ejecución no suelen prevenir la ejecución de todos los scripts. Su propósito principal (especialmente cuando se configuran de manera más estricta) es asegurarse de que confíes en que el script que estás ejecutando está firmado criptográficamente con un certificado.

Ámbitos de Política de Ejecución

Como has aprendido, las políticas de ejecución restringen la ejecución de scripts, pero PowerShell puede ejecutar scripts en muchos contextos diferentes. PowerShell ejecuta scripts bajo el contexto del usuario que ha iniciado sesión o bajo el contexto global de la máquina, a través de tareas programadas que se ejecutan como SYSTEM o dentro del ámbito de una única consola de PowerShell abierta.

Para adaptarse a todos estos contextos, PowerShell tiene cinco contextos o ámbitos diferentes en los que puedes definir una política de ejecución.

  • MachinePolicy – Este ámbito está limitado a un único equipo. Afecta a todos los usuarios que inician sesión en ese equipo, y un objeto de directiva de grupo de Active Directory lo establece. Cuando está definido, tiene prioridad sobre todos los demás ámbitos.
  • LocalMachine. Este es el ámbito predeterminado que afecta a todos los usuarios de la computadora y se almacena en la subclave del registro HKEY_LOCAL_MACHINE. Cuando establece una política de ejecución usando Set-ExecutionPolicy, este ámbito es el predeterminado.

La política de ejecución para LocalMachine se almacena en la clave del registro HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell.

  • UserPolicy – El ámbito UserPolicy afecta solo a un usuario en una computadora, y un objeto de directiva de grupo de Active Directory lo establece. No puede cambiar esta política con Set-ExecutionPolicy.
  • CurrentUser. El ámbito de política CurrentUser establece la política de ejecución solo para el usuario actual y se almacena en la colmena del registro HKEY_CURRENT_USER. No puede cambiar esta política con Set-ExecutionPolicy.

La política de ejecución para CurrentUser se almacena en la clave del registro HKEY_CURRENT_USER\SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell.

  • Process – Este ámbito define la política de ejecución para una sola sesión de PowerShell para un solo usuario. El ámbito de política de ejecución Process es la política de ejecución más detallada que puede definir. A diferencia de otras políticas de ejecución, esta política se guarda en una variable de entorno llamada PSExecutionPolicyPreference en lugar del registro.

Tipos de Políticas de Ejecución

Las políticas de ejecución tienen varios “niveles de seguridad”. Estos niveles dictan cuán estricta es la política de ejecución. Por ejemplo, puedes tener una política de ejecución en vigor que esencialmente no hace nada; está deshabilitada, pero, por otro lado, una política de ejecución puede deshabilitar completamente la ejecución de scripts.

Vamos a cubrir cada una de las formas en que puedes configurar el nivel de seguridad de una política de ejecución de menos a más restrictivo.

Unrestricted

La política menos restrictiva es una que no afecta en absoluto; es Unrestricted. Las políticas de ejecución Unrestricted están esencialmente deshabilitadas. Los usuarios pueden ejecutar todos los scripts independientemente de la confianza cuando una política de ejecución es Unrestricted.

Bypass

Al igual que el tipo Unrestricted, una política de ejecución configurada para Bypass, no bloquea nada.

Aunque Bypass y Unrestricted tienen un efecto similar, el tipo de política de ejecución Bypass técnicamente no es un tipo en absoluto. Omite una política de ejecución definida por completo.

Undefined

Aunque no se usa comúnmente, puedes esencialmente eliminar una política de ejecución configurándola como Undefined. Cuando configuras una política de ejecución a Undefined, PowerShell elimina por completo cualquier política de ejecución asignada del ámbito asignado.

En computadoras no Windows, la política de ejecución siempre está configurada como Unrestricted y no se puede cambiar.

Cuando todos los ámbitos están configurados como Undefined, PowerShell trata esencialmente todos los ámbitos como Restricted.

RemoteSigned

Como leíste antes, las políticas de ejecución se basan en la confianza obtenida mediante una firma digital en scripts. PowerShell también tiene en cuenta de dónde proviene ese script. ¿Fue creado en tu computadora local o por alguna persona aleatoria en Internet?

Los scripts creados en algún lugar que no sea tu computadora local no deberían confiarse inherentemente. Por eso PowerShell proporciona la política de ejecución RemoteSigned. La política de ejecución RemoteSigned garantiza que todos los scripts escritos en algún lugar que no sea tu computadora local estén firmados criptográficamente.

Puedes anular esta política de ejecución hasta cierto punto para archivos descargados de Internet utilizando el cmdlet Unblock-File. Obtén más información sobre este comportamiento un poco más adelante en la sección Cómo funciona la política RemoteSigned.

Para Windows Server, RemoteSigned se asigna como la política predeterminada.

AllSigned

Si deseas asegurarte de que todos los scripts de PowerShell estén firmados criptográficamente, establece la política de ejecución en AllSigned. Al igual que RemoteSigned, esta política de ejecución lleva el requisito de firma un paso más allá y exige que todos los scripts estén firmados antes de su ejecución.

Incluso si tienes la política de ejecución AllSigned configurada, aún puedes evitarla al eludirla, como aprenderás más adelante.

Restricted

La política de ejecución más restrictiva es Restringida. Cuando una política de ejecución está establecida como Restringida, absolutamente ningún script puede ejecutarse, independientemente de si son de confianza o no. Esta política deshabilita completamente la ejecución de scripts.

Además, a diferencia de los tipos menos restrictivos, el tipo Restringida garantiza que los archivos de formato de PowerShell y los archivos de configuración (PS1XML), los archivos de script de módulo (PSM1) y los perfiles de PowerShell no puedan ejecutarse.

Todos los clientes de Windows, por defecto, tienen una política de ejecución Restringida.

Técnicamente, Microsoft define una séptima política de ejecución llamada Predeterminada, pero el tipo es esencialmente otra etiqueta para RemoteSigned (en Windows Server) y Restricted (en Windows Clients).

Cómo funciona la Política RemoteSigned

Un escenario particular a señalar es cómo funciona la política de ejecución RemoteSigned. Esta política de ejecución (como has aprendido) evita que se ejecuten scripts que se hayan creado en algún lugar que no sea tu computadora local.

Pero, ¿cómo sabe PowerShell que el script se creó en otro lugar? Flujos de datos.

Comprender y consultar los flujos de datos NTFS

Cuando creas un archivo en un sistema de archivos NTFS, NTFS aplica un atributo de flujo de datos alternativo (ADS) al archivo. Un ADS tiene dos atributos de archivo: $Data y zone.Identifier. PowerShell utiliza el atributo zone.Identifier para identificar si un archivo de script de PowerShell se creó en otro lugar.

A diferencia de otros atributos como Comprimido o Solo lectura, los atributos ADS están ocultos en el Explorador de archivos. Sin embargo, mediante el uso de PowerShell, puedes inspeccionar estos flujos de datos.

Ejecuta el cmdlet Get-Item utilizando la ruta al script y el parámetro Stream como se muestra a continuación. En este ejemplo, Hello World.ps1 fue escrito en el equipo local. Observa que el único atributo asignado a la propiedad Stream es $DATA. No hay atributo ADS.

Get-Item '.\Hello World.ps1' -Stream *
ADS Stream output for local file

Ahora, ejecuta el mismo comando en un script descargado de Internet. Observa que ahora Get-Item devuelve otro objeto completamente diferente con un Stream de Zone.Identifier.

ADS Stream output for PowerShell file downloaded from internet

Una vez que sepas que un archivo tiene un ADS, puedes usar el comando Get-Content para descubrir la zona. La zona define de dónde proviene el archivo.

Get-Content .\Get-CertDetails.ps1 -Stream zone.identifier

Get-Content devolverá un valor ZoneId que representa la zona de donde proviene el archivo.

Zone ID Value

Los posibles valores de zona son:

Zone ID Zone
------- ---------------------
0       My Computer
1       Local Intranet Zone
2       Trusted sites Zone
3       Internet Zone
4       Restricted Sites Zone

Precedencia de la Política de Ejecución

Como se mencionó anteriormente, existen muchas políticas de ejecución diferentes al mismo tiempo. Todas estas políticas de ejecución, cuando se combinan, dictan la configuración de tu sesión actual. Cuando tienes múltiples políticas de ejecución en efecto, debes tener precedencia.

La precedencia de la política es el orden en el que PowerShell aplica diferentes políticas establecidas en diferentes ámbitos. Algunas políticas de ejecución tienen mayor prioridad que otras.

Cuando ejecutas Get-ExecutionPolicy -List, encontrarás todas las políticas de ejecución actualmente en efecto ordenadas de menor a mayor prioridad. Por ejemplo, dado que MachinePolicy tiene una prioridad más baja, las políticas LocalMachine y CurrentUser tendrán prioridad sobre ella.

Get-ExecutionPolicy cmdlet output

Trabajando con Políticas de Ejecución

Con suficiente comprensión del trasfondo de las políticas de ejecución, ¡vamos a adentrarnos en cómo trabajar con ellas! Para trabajar con las políticas de ejecución de PowerShell, tienes dos comandos a tu disposición: Get-ExecutionPolicy para descubrir las políticas definidas actualmente y Set-ExecutionPolicy para establecer nuevas políticas.

Obteniendo Políticas Asignadas Actualmente

Antes de que puedas empezar a cambiar las políticas de ejecución, necesitas saber con qué estás trabajando. Para hacerlo, cuentas con el comando Get-ExecutionPolicy. Este comando enumera todas las políticas asignadas actualmente en un equipo.

Cuando ejecutas directamente el comando Get-ExecutionPolicy en una consola de PowerShell sin parámetros, mostrará la política de ejecución establecida para tu sesión actual de PowerShell.

Get-ExecutionPolicy cmdlet output

Para ver la política de ejecución establecida para un ámbito, especifica el parámetro Scope utilizando el nombre del ámbito del que te gustaría ver los resultados.

Get-ExecutionPolicy -Scope Process
Get-ExecutionPolicy -Scope LocalMachine
Get-ExecutionPolicy cmdlet with scope parameter output

Para ver todos los ámbitos y sus políticas de ejecución, utiliza el parámetro List como se muestra a continuación.

Get-ExecutionPolicy -list
Get-ExecutionPolicy cmdlet displaying all scopes

Cambiando las Políticas de Ejecución

Una vez que sepas qué políticas de ejecución están actualmente asignadas, también puedes cambiarlas. Para cambiar la política en un solo equipo, tienes el comando Set-ExecutionPolicy a tu disposición. Pero, si estás en una organización, querrás cambiar políticas en masa. Si ese es el caso, siempre tienes la Política de Grupo si estás en un dominio de Active Directory.

Usando Set-ExecutionPolicy

Primero veamos cómo cambiar las políticas con el comando Set-ExecutionPolicy. Para hacerlo, abre PowerShell como administrador.

Ahora ejecuta el comando Set-ExecutionPolicy con un solo parámetro (ExecutionPolicy) proporcionando el nombre de la política de ejecución.

Set-ExecutionPolicy -ExecutionPolicy RemoteSigned

PowerShell luego preguntará si quieres cambiar la política de ejecución. Si lo deseas, escribe Y o A y presiona Enter.

Change Execution Policy

Algunos comandos de PowerShell necesitan ejecutar múltiples tareas adicionales para operar. Si en el ejemplo anterior escribes Y, PowerShell puede pedirte que continúes para cada paso. Si presionas A, continuará para todos los pasos subsiguientes.

Ejecutando Set-ExecutionPolicy Sin Solicitudes

Por defecto, cuando ejecutas Set-ExecutionPolicy, te preguntará si deseas cambiar la directiva de ejecución. Puedes omitir esta solicitud agregando el parámetro Force a tu comando. El uso del parámetro Force suprimirá todas las solicitudes de confirmación.

Set-ExecutionPolicy RemoteSigned -Force
Output of Set-ExecutionPolicy command when Force Parameter is used

Configuración de la directiva de ejecución de PowerShell a través del Registro

Dado que la mayoría de las directivas de ejecución se almacenan en el registro (excluyendo Process), también puedes cambiar las directivas directamente a través del registro.

Para cambiar las directivas de ejecución a través del registro:

  1. Abre el Editor del Registro de Windows (regedit) o la herramienta de edición de registro que elijas.

2. Navega hasta la clave del registro del ámbito de la directiva de ejecución que deseas cambiar.

LocalMachineHKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell

CurrentUserHKEY_CURRENT_USER\SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell

3. Haz clic derecho en la clave del registro y crea un nuevo valor de cadena llamado ExecutionPolicy.

4. Haz doble clic en el valor de cadena recién creado ExecutionPolicy y escribe el nombre de la directiva de ejecución deseada (Restricted, RemoteSigned, AllSigned, Unrestricted, o Undefined).

5. Crea otro valor de cadena en la misma clave llamado Ruta. El valor de cadena Ruta representa la ruta al motor de PowerShell. Asegúrate de que el valor de Ruta sea C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe, que apunta al motor de Windows PowerShell.

Registry path for ExecutionPolicy in registry for current user

La directiva de ejecución de UsuarioActual anula una política de MáquinaLocal. Si tienes una política de UsuarioActual configurada en el registro y intentas cambiar la política de ejecución a través del comando Set-ExecutionPolicy, que, por defecto, establece la política en el ámbito de MáquinaLocal, PowerShell devolverá un error mostrado a continuación.

Execution Policy Permission Denied

Establecimiento de la Política de Ejecución de PowerShell a través de Directiva de Grupo

Si estás en una organización con Active Directory, no vas a querer ir a todas tus máquinas Windows y ejecutar el cmdlet Set-ExecutionPolicy. En su lugar, puedes gestionar políticas en masa con Directiva de Grupo.

Para gestionar políticas de ejecución a través de GPO:

Crea el Objeto de Directiva de Grupo

  1. Abre la aplicación de Gestión de Directivas de Grupo en un controlador de dominio o en tu estación de trabajo unida al dominio.
Group Policy Management Console

2. Expande Dominios —> <tu bosque de Active Directory> —> Objetos de Directiva de Grupo.

Select Group Policy Objects node

3. Haz clic derecho en Objetos de Directiva de Grupo y selecciona Nuevo.

4. Dale un nombre a tu GPO. En este tutorial, el GPO se llama Directiva de Ejecución de PowerShell.

Create new Group Policy Object

5. Haz clic derecho en el GPO recién creado y haz clic en Editar.

6. Ve a Configuración del equipo\Configuración\Administrativas\Componentes de Windows\PowerShell de Windows.

Navigate to the setting in Group Policy Object

7. Abre el ajuste en el panel derecho, abre el ajuste Habilitar ejecución de scripts.

Turn on Script Execution Policy

8. En la casilla Habilitar ejecución de scripts, selecciona la opción Habilitado. Ahora puedes seleccionar una de las opciones mostradas a continuación:

9. Ahora cambia la Directiva de Ejecución a la directiva deseada.

  • Permitir solo scripts firmados – Permite la ejecución de todos los scripts cuando un editor de confianza los firma.
  • Permitir scripts locales y scripts firmados remotamente – Permite ejecutar scripts locales pero los scripts descargados de internet deben estar firmados por un editor de confianza.
  • Permitir todos los scripts – Permite ejecutar todos los scripts.
List Execution Policy

Asignar el Objeto de Directiva de Grupo

Una vez que hayas creado el GPO, es hora de asignarlo a tus computadoras objetivo. Para hacerlo, debes asignar el GPO a una Unidad Organizativa (OU) del Directorio Activo.

Si, en lugar de crear un nuevo GPO, editaste un GPO existente, ese GPO probablemente ya haya sido asignado a una OU.

  1. En Administración de directivas de grupo, navega hasta tu OU de elección yendo a Dominios —> <tu bosque de Active Directory> —> <Tu OU>.

2. Haz clic derecho en la OU y selecciona Vincular una GPO existente…

Link an Existing GPO…

3. Selecciona la GPO recién creada (Política de ejecución de PowerShell) y haz clic en Aceptar.

Select the GPO

Ahora deberías ver la GPO asignada a la OU como se muestra a continuación.

Link the Group Policy Object

En este punto, puedes esperar al intervalo de actualización de directivas de grupo definido o ejecutar el comando gpupdate en un equipo objetivo para forzar una actualización.

Restringir los Cambios de Política Local

Una vez que una GPO está en efecto y cambia la política de ejecución, los usuarios locales ya no pueden cambiar la política a través de la consola de PowerShell local. Si lo intentan, recibirán un error, como se muestra a continuación.

Error on trying to changing execution policy manually

Evitar Completamente la Política de Ejecución

Como se mencionó anteriormente, una política de ejecución no necesariamente está destinada a ser una medida de seguridad. ¿Por qué? Porque puedes evitarla completamente si así lo deseas de varias formas diferentes.

Usando el parámetro -ExecutionPolicy Bypass

A diferencia de otras políticas de ejecución, la política de Bypass suele establecerse no en la consola de PowerShell, sino que se pasa al motor powershell.exe para ejecutarse como administrador.

Por ejemplo, para ejecutar un script llamado Hello World.ps1 saltándose completamente cualquier política de ejecución, invoque powershell.exe, use el parámetro Bypass y proporcione la ruta del archivo como se muestra a continuación.

powershell.exe -executionpolicy bypass -file '.\Hello World.ps1'
ByPass Execution Policy using bypass execution policy

Lectura de scripts y ejecución de código sin formato

También puede evitar cualquier política de ejecución leyendo primero el contenido de un script y luego pasando ese contenido directamente al motor de PowerShell. Al hacerlo, se ejecuta cada comando individualmente y no como un script completo de una sola vez.

Como puede ver a continuación, la política de ejecución está establecida en Restringido, pero al leer el script y pasarlo a powershell.exe, sigue funcionando.

Este enfoque es similar a abrir un script en un editor de PowerShell como PowerShell ISE o Visual Studio Code, seleccionar una línea y presionar F8.

Get-Content '.\Hello World.ps1' | powershell.exe -noprofile
Alternative way to Bypass Execution Policy

Conclusión

Para este momento, debería saber todo lo que hay que saber sobre las políticas de ejecución de PowerShell. Aunque técnicamente no son una medida de seguridad, aún debería gestionarlas en su organización de acuerdo con las políticas organizativas.

Source:
https://adamtheautomator.com/set-executionpolicy/