I have a simple .ps1
script that basically just creates a directory. When I right-click on the script in Windows Explorer and select "Run with PowerShell", it gives the following error message:
Get-ExecutionPolicy : Windows PowerShell updated your execution policy successfully, but the setting is overridden by a policy defined at a more specific scope. Due to the override, your shell will retain its current effective execution policy of Unrestricted. Type "Get-ExecutionPolicy -List" to view your execution policy settings. For more information please see "Get-Help Set-ExecutionPolicy".
(I recorded my screen and typed all those above, as the window only flashed quickly. Also, if I run "powershell -NoExit C:\path\to\script.ps1", there is no error.
Interestingly, folder is still created.
However, if I open PowerShell myself and run the script like .\script.ps1
, it does not have any error.
Here is the output of Get-ExecutionPolicy -List
:
Scope ExecutionPolicy
----- ---------------
MachinePolicy Unrestricted
UserPolicy Undefined
Process Undefined
CurrentUser Undefined
LocalMachine Unrestricted
I think "Run with PowerShell" is trying to do something (like setting execution policy) before running the script, but I cannot see the full command that it invoked, and I don't know what scope it is trying to set execution policy for. Also, which of the above is more specific scope than which of the others?
I also don't have admin access to override this context menu item either. How should I get a clean execution?
Might be different from Unable to execute PowerShell Script using 'Run with Powershell' option as it seems my execution actually succeeded.
I expect to run the script cleanly from Windows Explorer, i.e., there should be no error outputs.
On Windows 10, the Windows PowerShell Run with PowerShell
shortcut menu command (defined in the registry) attempts a process-specific execution policy override via the CLI, by calling Set-ExecutionPolicy -Scope Process Bypass
as part of code passed to the -Command
parameter.
However, because your machine's execution policy is governed by a GPO (Group Policy Object), as indicated by the MachinePolicy
output line having a value other than Undefined
, neither overrides via the CLI's -ExecutionPolicy
parameter nor via Set-ExecutionPolicy
are effective.
This is what the error message is trying to tell you; specifically, it means: I applied the change you requested, but it has no effect.
The error itself does not stop execution, which continues with the GPO-controlled policy in effect.
Given that the effective GPO policy is Unrestricted
in your case (which should probably be RemoteSigned
for better security), your scripts will still execute and you can ignore the error message.
To make the error message go away, one option is to remove the Set-ExecutionPolicy
call from the command definition in the registry.
Its modification requires elevation, i.e. administrative privileges, due to being in the HKEY_LOCAL_MACHINE
registry hive; however, it is possible to define user-specific equivalents in the HKEY_CURRENT_USER
hive, which therefore do not require elevation - see below.
The other option is to deactivate the relevant GPO, which - given that it is the MachinePolicy
- at the very least requires elevation too, but is typically not under your control in a domain environment.
Set-Execution
call and therefore suppress the warning:On Windows 10, the following should work (I cannot personally verify any longer), based on the information in the bottom section of this answer, adapted to target whatever file type is currently registered for .ps1
files, which may differ from the default, notably if you have Visual Studio Code installed:
# Determine the registry key path, based on the HKEY_CURRENT_USER
# equivalent of the file-type key.
$regKey = 'registry::HKEY_CURRENT_USER\Software\Classes\{0}\shell\Run with PowerShell\Command' -f (Get-ItemPropertyValue registry::HKEY_CLASSES_ROOT\.ps1 '(Default)')
# Create the key, if necessary.
if (-not (Test-Path $regKey)) { $null = New-Item -Force -ErrorAction Stop $regKey }
# Define the command line, without Set-ExecutionPolicy and with -NoExit.
Set-ItemProperty $regKey '(Default)' '"C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -NoExit -File "%1"'
This creates a HKEY_CURRENT_USER
equivalent of the (potentially) HKEY_LOCAL_MACHINE
-housed shortcut-menu command definition, which should override the latter, given that the HKEY_CLASSES_ROOT
hive, through which the shortcut-menu definitions are loaded, is a composite view of the former two hives' Software\Classes
paths, with the user-level definitions taking precedence.
Also note that -NoExit
was added to keep the session alive after script execution and therefore the window open.
If you do have administrative privileges, you can replace HKEY_CURRENT_USER
with HKEY_LOCAL_MACHINE
in the code above and run it with elevation.
On Windows 11, the problem no longer arises, because the Windows PowerShell CLI call configured there no longer tries to change the execution policy.
However, you may still want to modify the call, namely to include the -NoExit
switch too (to keep the session alive and the window open after script execution): see this answer.
In PowerShell (Core) 7 - which is no longer supported on Windows 10 - the problem also doesn't arise: no attempt is made to set the execution policy.
Fundamentally, the shortcut-menu commands are only available if you install PowerShell 7 via its MSI package, where you get the option to install commands for folders and drives, as well as for running individual *.ps1
files (as in Windows PowerShell).
To see them, you must hold down Shift while right-clicking.
The folder/drive-level commands (PowerShell 7
submenu) open an interactive session in the target folder or drive.
The *.ps1
-file-level command, stored at HKEY_CLASSES_ROOT\Microsoft.PowerShellScript.1\Shell\PowerShell7x64\Command
, as of PowerShell 7.4.3:
appears to be broken: at least on my machine, it is never shown.
is misdefined:
C:\Program Files\PowerShell\7\pwsh.exe -Command "$host.UI.RawUI.WindowTitle = 'PowerShell 7 (x64)'; & '%1'"
"..."
enclosure, which is required to the path containing spaces - bizarrely, this is not in and of itself a problem (it also afflicts the folder/drive-level commands, which do work).'...'
isn't robust, given that '
is a legal character in paths.Even if it did work as intended, you may also want to modify it to include -NoExit
, to prevent the window from auto-closing after script execution.