При попытке запустить .ps1 PowerShell может выдать ошибку и отказаться выполнять скрипт. Текст ошибки зависит от политики выполнения (execution policy). При политике Restricted будет сообщение о том, что выполнение сценариев отключено в системе. При AllSigned или RemoteSigned — что файл не имеет цифровой подписи.

По умолчанию в Windows PowerShell 5.1 на клиентских Windows действует Restricted, на Windows Server — RemoteSigned. В PowerShell 7 на Windows по умолчанию RemoteSigned, на Linux и macOS политика всегда Unrestricted и не меняется.

Политика выполнения не является механизмом защиты. Microsoft прямо пишет, что это защита от случайного запуска, а не граница безопасности: содержимое скрипта можно просто вставить в консоль.

Политики выполнения

Политика Что разрешено
Restricted Только интерактивные команды. Скрипты, модули .psm1, файлы .ps1xml и профили не запускаются
AllSigned Только скрипты, подписанные доверенным издателем, включая свои локальные
RemoteSigned Локальные скрипты без подписи. Скачанные из интернета — только с подписью или после разблокировки
Unrestricted Любые скрипты. Для файлов не из зоны интрасети выводится предупреждение
Bypass Всё без ограничений и без предупреждений
Undefined Политика в этой области не задана

Default — не отдельная политика, а сброс к значению по умолчанию для этой системы.

Посмотреть текущую политику

Действующая политика:

Get-ExecutionPolicy

Политики по всем областям, в порядке приоритета:

Get-ExecutionPolicy -List
        Scope ExecutionPolicy
        ----- ---------------
MachinePolicy       Undefined
   UserPolicy       Undefined
      Process       Undefined
  CurrentUser    RemoteSigned
 LocalMachine       AllSigned

Действует первая сверху политика, отличная от Undefined. В примере это RemoteSigned из области CurrentUser, хотя для компьютера задана AllSigned.

Области:

  • MachinePolicy и UserPolicy — задаются групповыми политиками для компьютера и пользователя. Командлетом их изменить нельзя;
  • Process — только текущий сеанс PowerShell, хранится в переменной $Env:PSExecutionPolicyPreference и пропадает при закрытии окна;
  • CurrentUser — текущий пользователь, HKCU:\Software\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell, параметр ExecutionPolicy;
  • LocalMachine — все пользователи компьютера, HKLM:\Software\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell.

Пути в реестре указаны для Windows PowerShell 5.1. PowerShell 7 хранит политику для CurrentUser и LocalMachine в файлах powershell.config.json, поэтому у Windows PowerShell и PowerShell 7 на одном компьютере политики могут быть разными.

Разрешить запуск скриптов

Для текущего пользователя, прав администратора не нужно:

Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser

Для всех пользователей компьютера, из консоли, запущенной от администратора:

Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope LocalMachine

Изменение действует сразу, перезапускать PowerShell не нужно. RemoteSigned для большинства задач достаточно: свои скрипты запускаются, скачанные — только после проверки. Bypass и Unrestricted на постоянной основе ставить не стоит.

Учтите, что команда может выполниться без ошибки, но ничего не изменить. Если вы задали RemoteSigned для LocalMachine, а в CurrentUser стоит Restricted, действовать будет Restricted. После изменения проверьте результат через Get-ExecutionPolicy -List.

Чтобы убрать политику в области, задайте Undefined:

Set-ExecutionPolicy -ExecutionPolicy Undefined -Scope CurrentUser

Запустить один скрипт, не меняя политику

Для одного запуска политику можно задать при старте PowerShell:

powershell.exe -NoProfile -ExecutionPolicy Bypass -File C:\PS\script.ps1

В PowerShell 7 то же самое делается через pwsh.exe. Политика действует только в этом процессе и его дочерних процессах.

Разблокировать скачанный скрипт

При политике RemoteSigned не запускаются неподписанные скрипты, скачанные из интернета. Браузер помечает такие файлы альтернативным потоком Zone.Identifier. Проверить, есть ли пометка:

Get-Item C:\PS\script.ps1 -Stream Zone.Identifier

Снять пометку с файла или со всех скриптов в папке:

Unblock-File C:\PS\script.ps1
Get-ChildItem C:\PS\*.ps1 | Unblock-File

Файлы, скачанные через curl.exe, Invoke-WebRequest или Invoke-RestMethod, могут не получить такую пометку, и RemoteSigned их не остановит.

Если политику задаёт GPO

Если в Get-ExecutionPolicy -List в областях MachinePolicy или UserPolicy стоит что-то кроме Undefined, политику задаёт групповая политика. Она перекрывает все остальные области, включая Process. В этом случае не помогут ни Set-ExecutionPolicy, ни запуск с -ExecutionPolicy Bypass: при попытке изменить политику PowerShell выдаст ошибку, что она переопределена политикой с более конкретной областью.

Политику задаёт параметр GPO Turn on Script Execution в разделе:

Computer Configuration (или User Configuration) → Administrative Templates → Windows Components → Windows PowerShell

Значение GPO Политика выполнения
Disabled Restricted
Enabled: Allow only signed scripts AllSigned
Enabled: Allow local scripts and remote signed scripts RemoteSigned
Enabled: Allow all scripts Unrestricted
Not Configured Действует политика, заданная в PowerShell

Политика из раздела компьютера имеет приоритет над политикой из раздела пользователя. Варианта Bypass в GPO нет.

Правильный путь — изменить GPO или вывести компьютер из-под её действия. Параметр GPO лежит в реестре в ключе HKLM\SOFTWARE\Policies\Microsoft\Windows\PowerShell (значения EnableScripts и ExecutionPolicy), и его можно поправить вручную, но при следующем обновлении групповых политик значение вернётся.

Источники