По своему дизайну двойной щелчок (открытие) *.ps1
файлов из оболочки Windows (Рабочий стол, Проводник, панель задач, меню Пуск) делает не выполнить их - вместо этого они открыты для редактирования в Блокноте или PowerShell ISE, в зависимости от версии Windows / PowerShell
Однако, поскольку по крайней мере Windows 7* контекстное меню для файлов *.ps1
содержит команду Run with PowerShell
, которая делает , вызывая скрипт под рукой;это может быть достаточным для ваших целей, но этот метод вызова имеет ограничения - подробности см. в нижнем разделе.
Если вы хотите переопределить двойной щелчок / открытие, чтобы он выполнял *.ps1
сценарии , у вас есть две опции:
Метод GUI:
Используйте File Explorer, чтобы PowerShell выполнял .ps1
файлов по умолчанию:
- Щелкните правой кнопкой мыши файл
.ps1
и выберите Properties
. - Нажмите
Change...
рядом с меткой Opens with:
. - Нажмите
More apps
в нижней части списка и прокрутите вниз до Look for another app on this PC
- Найдите или вставьте путь к файлу
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
и отправьте.
Этот метод не позволяет контролировать особенности вызова PowerShell ;в результате вы получите следующее поведение:
Переопределение действует только для текущего пользователя - что, вероятно, хорошо, как и другиепользователи могут не ожидать этого изменения, которое может привести к нежелательному выполнению сценария.
Какая бы ни была действующая политика выполнения, будет соблюдаться;Например, если действует Restricted
, вызов вообще не будет выполнен.
Как и в случае команды Run in PowerShell
по умолчанию, окно, в котором запускается скрипт, автоматически закрывается 1079 *, если только сценарий явно не запрашивает пользователя перед выходом.
Чтобы лучше контролировать, как PowerShell вызывает сценарий, используйте программный метод, показанный ниже.
Программный метод:
Измените реестр , чтобы переопределить команду контекстного меню Open
для файлов *.ps1
в HKEY_CLASSES_ROOT\Microsoft.PowerShellScript.1\shell\Open\Command
, как показано ниже.
Важно : Если вы ранее использовали метод GUI выше, вы должны вручную удалить базовое определение реестра, в противном случае переопределение программы не вступит в силу:
Открыть regedit.exe
(требуются права администратора)
Перейдите к HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.ps1
и удалить эту клавишу.
Примечание: по крайней мере в Windows 10, пытаясь удалить этот ключ programmatics - например, с reg delete HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.ps1\UserChoice /f
происходит сбой из-за проблем с разрешениями, даже при работе от имени администратора.
Примечание :
Код переопределяет команду только для текущего пользователя , что, вероятно, является лучшим подходом, поскольку другие пользователи могут не ожидать этого изменения, что может привести к нежелательному выполнению сценария.
- Если вы по-прежнему хотите внести изменения для всех пользователей, установите
$forAllUsers
на $true
ниже, но учтите, что тогда вам придется запустить код с повышенными правами (от имени администратора).
В отличие от стандартной команды Run in PowerShell
, приведенный ниже код сохраняет окно, в котором выполняется скрипт open и сеанс живой .
Какая бы ни была действующая политика выполнения, будет соблюдаться;например, если действует Restricted
, вызов вообще не будет выполнен.
- В приведенном ниже коде вы можете предвосхитить
-File
что-то вроде -ExecutionPolicy RemoteSigned
, чтобы переопределить действующую политику, но я предлагаюне выбирая менее ограничительного значения, чем значение по соображениям безопасности.
Как и в случае стандартной команды Run in PowerShell
, сценарий выполняется в каталоге, в котором он находится, в качестве рабочегокаталог (текущее местоположение).
Чтобы настроить точную команду вызова, измените строку $cmd = ...
ниже.
- В частности, чтобы указать PowerShell Core вместо Windows PowerShell, замените
powershell.exe
с pwsh.exe
.
# Specify if the change should apply to the CURRENT USER only, or to ALL users.
# NOTE: If you set this to $true - which is NOT ADVISABLE -
# you'll need to run this code command ELEVATED (as administrator)
$forAllUsers = $false
# Determine the chosen scope's target registry key path.
$targetKey = "$(('HKCU', 'HKLM')[$forAllUsers]):\Software\Classes\Microsoft.PowerShellScript.1\shell\Open\Command"
# In the user-specific hive (HKCU: == HKEY_CURRENT_USER), the target key
# doesn't exist by default (whereas it does in the local-machine hive (HLKM: == HKEY_LOCAL_MACHINE)),
# so we need to make sure that it exists.
if (-not $forAllUsers) {
$null = New-Item -Force $targetKey -ErrorAction Stop
}
# Specify the command to use when opening / double-clicking *.ps1 scripts:
# As written here:
# * The profiles are loaded (add -NoProfile to change).
# * The current execution policy is respected (add -ExecutionPolicy <policy>)
# * The window stays open after the script exits (remove -NoExit to change)
# * Windows PowerShell is targeted - to target PowerShell *Core* instead,
# replace 'powershell.exe' with 'pwsh.exe'
# For help with all parameters, see https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_powershell_exe
$cmd = "`"$((Get-Command powershell.exe)[0].Source)`" -noexit -file `"%1`""
#"# Write the command to the registry.
Set-ItemProperty -LiteralPath $targetKey -Name '(default)' -Value $cmd
Предопределенная команда контекстного меню Run in PowerShell
:
Она определена в разделе реестра HKEY_CLASSES_ROOT\Microsoft.PowerShellScript.1\shell\0\Command
(в Windows 10) следующим образом:
"C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" "-Command" "if((Get-ExecutionPolicy ) -ne 'AllSigned') { Set-ExecutionPolicy -Scope Process Bypass }; & '%1'"
Если не действует политика выполнения AllSigned
- в этом случае только подписано сценарии могут быть выполнены, но выполняются без запроса - команда пытается установить политику выполнения для вызванного процесса равной Bypass
, что означает, что любой сценарийможет быть выполнен, но только после того, как пользователь ответит на запрос подтверждения заранее (независимо от того, подписан ли скрипт или нет, и был ли он загружен из Интернета или нет).
- По крайней мере, в более ранних выпусках Windows 7 / версии PowerShells, команда была неверно определена [1] таким образом, что фактически игнорировалась попытка установить политику выполнения процесса, что означало, что независимо от того, какая политика выполнения постоянно настраивалась, применялась - и нетбыло показано приглашение подтверждения.
Если целевой сценарий явно не приостанавливает ожидание ввода пользователя перед выходом, окно, в котором сценарий автоматически закрывается после завершения сценария, поэтому вы можете не увидеть его вывод.
Целевой сценарий выполняется в каталоге, в котором он расположен в качестве рабочего каталога (текущее местоположение)
[1] Ранее сломанное определение команды было "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" "-file" "%1" "-Command" "if((Get-ExecutionPolicy ) -ne AllSigned) { Set-ExecutionPolicy -Scope Process Bypass }"
, что означало, что что-либо после -file "%1"
было переданов качестве аргументов для файла "%1"
вместо предполагаемого выполнения команд, следующих за -Command
;дополнительно - спорный вопрос - операнд AllSigned
должен быть заключен в кавычки.