I like to keep it simple, but I think that “secure-by-default” description of PowerShell is telling the story wrong, like saying that powershell is just a glorified command prompt or a modern replacement for VB Script. It not setting the right context and showing which goal we want to reach.
I prefer to start with this quote: “With great power comes great responsibility”.
Running a powershell script is like running any other application under your user context, as some applications do even some cmd-let requires to run with higher priviledges.
Double-Click on a PS1 file
And let me start showing you how can be secure, if you double-click on a “ps1” your code will not run, but will be opened in notepad. That’s a feature, not a bug! It’s simple and extremely effective. Think about how many times you’ve run a batch file by mistake!
Execution Policies
When you run a powershell script you load your configuration file and your run scripts according to the policy set . Learn more about execution policy from get-help about_execution_policy.
Execution Policy Types
- Restricted No Script either local, remote or downloaded can be executed on the system.
- AllSigned All script that are ran require to be digitally signed.
- RemoteSigned All remote scripts (UNC) or downloaded need to be signed.
- Unrestricted No signature for any type of script is required.
Each of these policies can be applied to different scopes to control who is affected by them, the scopes are:
- MachinePolicy: The execution policy set by a Group Policy for all users.
- UserPolicy: The execution policy set by a Group Policy for the current user.
- Process: The execution policy that is set for the current Windows PowerShell process.
- CurrentUser: The execution policy that is set for the current user.
- LocalMachine: The execution policy that is set for all users.
1 2 3 4 5 6 7 8 9 |
PS /Users/paolofrigo> Get-ExecutionPolicy -list Scope ExecutionPolicy ----- --------------- MachinePolicy Unrestricted UserPolicy Unrestricted Process Unrestricted CurrentUser Unrestricted LocalMachine Unrestricted |
Workarounds
- get-help about-signing (the best way)
- bypass execution policy (by set-executionpolicy or run_with_powershell)
- get-help unblock-file
So why execution policies matters?
Because it can prevent to run unintentionally, like double-click on a “ps1”.
Many cmd-lets have a “-WhatIf” and “-Confirm” flag, this is a security feature to check like a dry-run the before the execution what to will happen if the cmd-let is triggered.
Code Signing is extremely important, proving identity and detecting changes after being signed.
Scopes
Another important security feature are Scopes.
PowerShell protects access to variables, aliases, functions, and PowerShell drives (PSDrives) by limiting where they can be read and changed. By enforcing a few simple rules for scope, PowerShell helps to ensure that you do not inadvertently change an item that should not be changed.
If you create an item in a scope, and the item shares its name with an item in a different scope, the original item might be hidden under the new item. But, it is not overridden or changed.