Every now and then I like to do a little bit of bug hunting in
Grumpy Admin here, I am super grumpy this morning, my second cup of coffee made by another person this morning is horrible and made me think of something that is a bit naughty and mean as I was too polite to complain about my watered down pig swill this morning, so will drink it slow and hope someone offers to make a fresh one before I finish it! I am using screenshots in this blog post, just so you know that I am not pulling your leg or bluffing. Not that this is actually that technical, the Execution-Policies setting in Powershell were never meant to be a real security control by Microsoft. They even inserted methods of bypassing it built in!!!
So the story, we all have done this I am sure, sometimes you build a new machine, copy across a small Powershell script and tried to execute it
and you come up with this! (click image to make it bigger)
As you can see the default execution policy is applied and this is Restricted, grr this makes me grumpy as I really wanted to run my script- Now there a few things we can do about this – I now assume that you know all about execution policies, right?
Don’t forget you can check your policy by doing the following, this will show you the policy setting and scope!
now we can change this to either of the following :- (extract from Get-Help Set-ExecutionPolicy )
Restricted: Does not load configuration files or run scripts. “Restricted” is the default execution policy.
AllSigned: Requires that all scripts and configuration files be signed by a trusted publisher, including scripts that you write on
the local computer.
RemoteSigned: Requires that all scripts and configuration files downloaded from the Internet be signed by a trusted publisher.
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.
Undefined: Removes the currently assigned execution policy from the current scope. This parameter will not
remove an execution policy that is set in a Group Policy scope.
Revision is great isn’t it! This is all well and good if you are in a Admin context, when you try to execute the Set-ExecutionPolicy cmdlet -If you are not an Admin the Set-ExecutionPolicy will tell you to go away!!! So what if this script doesn’t need admin rights, so you want to run it in the user context, normally as you’re too lazy to reload and relaunch and type in an admin account password or click the UAC dialog box!
More importantly what if a junior member of staff is watching/learning from you and laughing at you because you got the user privilege context wrong. Grumpy admin doesn’t like to be laughed at regardless of the fact he is human and makes mistakes (more often than you will know, but grumpy admin is also very adept at covering his tracks!) and given the quality of the coffee this morning, he would no doubt snap and do an RM -RF / on his life!
So is there a way we can bypass or override this execution policy and run our script without having to set the execution policy! The answer is YES! In order to test and demonstrate the methods of how to override the execution policy I need a basic script to test it with
Introducing a basic script! We shall call this script bypass.ps1,
Write-Host “Grumpy Admin has bypassed the Execution Policy and ran my function (which may have some grumpy or nasty code in it) from
a script file .ps1″
I saved this in the c:\ for testing purposes. We all know grumpy admin doesn’t like typing and long paths are just a waste of keyboard effort!
There are quite a few way to override the execution policy, some simple, some complex, only going to cover a couple of methods – I must stress that this is just overriding the policy no an privilege escalation attack! (Oh I might blog about one of them at a later date!) This is just so you can get a .ps1 running quickly without the hassle of having to set the execution policy.
The first method is not really a method at all it is a cheat! But it is the basic method that all the other methods I will document today apply! Just type the code in or do as grumpy admin would do and cut and paste and Powershell will execute the code. But that is a cheat, we want to load the .ps1 script without having open it, cut and paste and stuff like that!
So what we can do is automate this basic principle of typing the commands in and then executing them! And the tool we are going to do
that with is the best feature of Powershell… The pipeline
So lets start with the most basic common situation you might find yourself in – An non administrative command prompt window.
Here we can use the old dos command TYPE to pipe the contents of the file to Powershell
So our command line will be
TYPE c:\bypass.ps1 | powershell -noprofile –
and you get the following output
This works a treat and works from a dos prompt! Yippy – this could get nasty if you download code and allow your users access to a basic dos prompt. Locking down and application white listing isn’t a dirty word!
What if we are inside of Powershell already? Well that is also simple – we can use the Get-Content cmdlet and send the content right down
the pipeline as it was designed to do!!! 🙂
So in Powershell our command line will be :-
Get-Content .\bypass.ps1 | powershell -noprofile –
now grumpy admin doesn’t like typing much so top tip is :- you can use the GC Alias to shorten the Get-Content cmdlet! There don’t say I’m not being nice to you all!
or you can just use the great inbuilt bypass flag from the launching process via an cmd line – very useful for dos batch files, so you can launch a batch file which calls Powershell scripts without worrying about the Execution Policy.
So your command line would be :-
powershell -executionpolicy bypass -file .\bypass.ps1
There are many other things you can do, this is just the very surface, of using Powershell in a naughty way! So the bottom line is – the
Set-ExecutionPolicy is nothing but a minor stumbling block that can be easily overridden and well just makes people like me more
grumpy when we either forget to set it and it prevents us from running our scripts!