19

The documentation on the topic only provides this:

Unrestricted. Loads all configuration files and runs all scripts. If you run an unsigned script that was downloaded from the Internet, you are prompted for permission before it runs.

Bypass. Nothing is blocked and there are no warnings or prompts.

To me it seems like the two would accept any scripts, but to my surprise it's not the case. Bypass seems to block execution in some cases.

So, what is the difference between the two ?

Mark Wragg
  • 22,105
  • 7
  • 39
  • 68
scharette
  • 9,437
  • 8
  • 33
  • 67
  • My understanding of these is that you have the option to change the execution policy permanently to `unrestricted` or to use `bypass` to ignore the set execution policy for the specific run of powershell.exe. As such they should yield the same result. Can you provide a code example that demonstrates where they work differently? – Mark Wragg May 16 '18 at 12:38
  • Thank you for your comment, it is hard for me to provide code example since it is not related to code but more to a _"scenario"_. So, a classic example would be to run an unsigned script that was created on another machine. – scharette May 16 '18 at 12:43
  • BTW, if the two yield the exact same result why in the world would Microsoft add this policy ? – scharette May 16 '18 at 12:44
  • 1
    Because you can do this: `set-executionpolicy unrestricted` or you can do this `powershell.exe .\somescript.ps1 -executionpolicy bypass`. The latter doesn't change the system policy, it just ignores it. That way you can run a one of script that needs to bypass the policy without having to change the system state. – Mark Wragg May 16 '18 at 12:47
  • I see the nuance. I thought that `Unblock-File` was serving this exact purpose though... I gotta admit all these policies are really confusing in my opinion. – scharette May 16 '18 at 13:14
  • `Unblock-File` wouldn't help you if the system policy was set to `Restricted`. – Mark Wragg May 16 '18 at 13:15
  • Based on a comment above, it may be analogous to the difference between sudo and logging in as root. –  Oct 12 '18 at 04:17
  • @HaakonDahl Which comment do you refer to exactly ? – scharette Oct 12 '18 at 04:22
  • Actually, the first two comments by Mark Wragg. The analogy is mine, so no blame affixes to Wragg if it's all hosed up. –  Oct 15 '18 at 09:42

2 Answers2

25

Per the comments, there should be no particular difference with how these execution policies behave (except those noted by @DennisSimpson in his answer, where on Windows use of "Unrestricted" may still result in a prompt if the file was detected as downloaded from the internet). Typically, Bypass is used when you are temporarily changing the execution policy during a single run of Powershell.exe, where as Unrestricted is used if you wish to permanently change the setting for the execution policy for one of the system scopes (MachinePolicy, UserPolicy, Process, CurrentUser, LocalMachine).

Some examples:

  1. You are on a system where you want to change the execution policy to be permanently unrestricted so that any user could run any PowerShell script without issue. You would run:

     Set-ExecutionPolicy Unrestricted
    
  2. You are on a system where the execution policy blocks your script, but you want to run it via PowerShell and ignore the execution policy when run. You would run:

     powershell.exe .\yourscript.ps1 -executionpolicy bypass
    
  3. You run Powershell.exe on a system where the execution policy blocks the execution of scripts, but you want to change this policy just for the life of the interactive powershell.exe session that you're in. You would run:

      Set-ExecutionPolicy Bypass -Scope Process
    
Mark Wragg
  • 22,105
  • 7
  • 39
  • 68
  • 1
    I'll wait for other opinions before accepting just to make sure. +1 for examples though, really helpful! – scharette May 16 '18 at 13:43
  • I don't agree with the "temporary" vs "permanent" nature of this answer. All PowerShell execution policies can be applied permanently via `Set-ExecutionPolicy` or used temporarily via `-ExecutionPolicy` on the PowerShell command line. Whether one is "Intended" for one purpose or the other seems rather subjective and is not described as such in the official documentation. – LesFerch Jan 24 '23 at 21:09
  • @LesFerch the word "bypass" (by its very definition) does seem to suggest that the intention is to temporarily work around the policy rather than permanently change it. And by using "bypass" in your code you make it more obvious to others reading it that your intention was not to make a permanent change. – Mark Wragg Jan 25 '23 at 09:40
  • They're just identifiers. What they imply or suggest in English is much less important than what they actually do. The answer from @DennisSimpson clearly explains how they differ in functionality. – LesFerch Jan 25 '23 at 14:02
  • 1
    He clarifies the difference between the Bypass and Unrestricted execution policies. That is, Unrestricted only differs from Bypass in that it, as per Microsoft, [Warns the user before running scripts and configuration files that are not from the local intranet zone](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_execution_policies) which, as @DennisSimpson points out, is only applicable to NTFS and browsers that save ADS. – LesFerch Jan 25 '23 at 19:04
4

The difference is in the descriptions you gave in the question. Unrestricted allows you to indulge in the illusion that all computers run windows, only use NTFS, and only download things with browsers that save ADS. In fact, if you save a file in windows to a FAT filesystem or network share that isn't using NTFS on the server, or download it another way such as with git, powershell believes it is locally created no matter where it came from. Bypass doesn't check for any of this and just runs everything. Unrestricted is supposed to warn you of things it thinks might be dangerous but isn't able to reliably check or determine. Use whichever tickles your fancy.

PS> rm -path file.ps1 -stream zone.identifier
Discuss...