4

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.

2 Answers 2

4

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.

  • As an aside: It is unfortunate that what should be a warning is surfaced as an error, but it was decided not to change that in the interest of backward compatibility; see GitHub issue #12032

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.


Modifying / overriding the command to omit the 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'"
      • A fundamentally conceptual problem is that the executable path lacks "..." 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).
      • The secondary problem is that enclosing a path in '...' 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.

Sign up to request clarification or add additional context in comments.

9 Comments

OH... That makes sense now... Any way I can create a user-local version of "Run with PowerShell" that runs the script without setting process level execution policy?
@charlesz, yes, as (now) noted in the answer, you can create equivalent definitions in the HKEY_CURRENT_USER registry hive.
"but it was decided not to change that in the interest of backward compatibility" a constant thorn in the way of PowerShell progress..
@mklement0 Yes. I am on Windows 10. Let me try next time I work on this.
Made it work now. Thanks! @mklement0 Only caveat is that I use VS Code so it needed to be under "VSCode.ps1" instead of "Microsoft.PowerShellScript.1". "0" could be anything, and as long as it has a default value set, it uses that value as the context menu text.
|
0

On Windows 11, as of today, right-click + "Run with PowerShell" does not work.

The policy error still appears, even with RemoteSigned set at all scopes.

2 Comments

Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.
This does not really answer the question. If you have a different question, you can ask it by clicking Ask Question. To get notified when this question gets new answers, you can follow this question. Once you have enough reputation, you can also add a bounty to draw more attention to this question. - From Review

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.