Fixing PowerShell ExecutionPolicy and GPO

PowerShell has an annoying, to me, idea about security. Yeah, yeah, we all love security, blah blah blah. But…

But I make heavy use of my own PowerShell scripting for use in my Lab.

I even wrote my own PowerShell module (see PassiveInstall ) to simplify much of the scripting I do around automating application installs and configuration for packaging. It allows me to right click on a PS1 file and select “Run with PowerShell” from the menu and the script will automatically elevate if needed.

And I’m not about to sign all those scripts. So I set a GPO for the lab machines that sets the PowerShell ExecutionPolicy on those machines to Unrestricted.

But when I do the right-click, a curious thing occurs. Every script starts with a small error line complaining that I am trying to set the executionpolicy.

Typical PowerShell output with unnecessary and inconsequential error

If a GPO sets the execution policy, the command line is not allowed to change that setting. That makes sense to me. But not if the command line is asking for the same, or even more, restrictions than the GPO. I mean, if the GPO says unrestricted, why can’t I start a script and request a policy of Signed?

Fortunately for me, when this situation occurs, it spits out this red error text in the output, but then continues on executing without changing the policy. And I set the policy I wanted in the GPO so the scripts all run fine. So I had been ignoring them and being only slightly pissed off about it. I had been thinking that it must have been something that I did in the PassiveInstall module, and at some point I’d look into it.

So today was that point. And it wasn’t my module. It was the built in File Type Association shell integration for PowerShell.

The menu for the right click on a .ps1 file is created via the FTA. In this case, the FTA definition starts in the Windows Registry as shown here:

The default value of that key is referred to as a ProgID. The ProgID is also stored under the classes key as shown here:

The ProgID, in this case, defines a Icon for display of the filetype, and the Shell integration menus. You can see three menu items shown as keys 0, Edit, and Open. I highlighted the 0 entry, which reveals a MuiVerb entry pointing to a resource inside the PowerShell.Exe file. This tells explorer.exe to pull that resource out for the verb to place on the menu, which is where we are getting the string “Run with PowerShell” from. (By the way, “Edit” and “Open” are standard verbs that are set just by the name of the key; if you look under their keys you see there is no MuiVerb entry).

Looking under the 0\Command key we see the following:

The full text of that command is given here:

“C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe” “-Command” “if((Get-ExecutionPolicy ) -ne ‘AllSigned’) { Set-ExecutionPolicy -Scope Process Bypass }; & ‘%1′”

So it is the command that is looking at the current execution policy and deciding that if the current policy is not AllSigned that we should run PowerShell against the file using ByPass.

So I fix this by changing the entry to :

“C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe” “-Command” “if((Get-ExecutionPolicy ) -ne ‘AllSigned’ -and (Get-ExecutionPolicy -Scope MachinePolicy ) -eq ‘Undefined’ ) { Set-ExecutionPolicy -Scope Process Bypass }; & ‘%1′”

And the problem is solved:

By Tim Mangan

Tim is a Microsoft MVP, and a Citrix CTP Fellow. He is an expert in App-V and MSIX.