Please don’t misunderstand me, you really need Powershell and all it’s magic if you are a pentester, don’t you?

But what can you do if some policy is blocking  access to powershell.exe?  Yes, this is a well known problem and there are many solutions. In my article I just want to focus on a quick & dirty bypass. The idea is to have e C# assembly  which will execute our powershell scripts. Nothing new, of course 😉

First of all, why don’t we need powershell.exe for executing our .ps1 scripts?

Because powershell scripting, just like C#,  is only a “frontend” to the .Net Framework , they are just languages.

In C#, you need to compile the  programs  in order to execute them, unlike Powershell scripts which are interpreted by Powershell.exe

Given that  Powershell.exe is  only an  interpreter for the .NET assembly “System.Management.Automation” ,  it should be possible to interact with this object in our C# program and execute .ps1 scripts.

That’s exactly what the following code does:


using System.Collections.ObjectModel; 
using System.Management.Automation; 
using System.Management.Automation.Runspaces; 
using System.IO;
using System;
using System.Text;
namespace PSLess
 class PSLess
   static void Main(string[] args)
     if(args.Length ==0)
     string script=LoadScript(args[0]);
     string s=RunScript(script);
 private static string LoadScript(string filename) 
   string buffer ="";
   try {
    buffer = File.ReadAllText(filename);
   catch (Exception e) 
  return buffer;
 private static string RunScript(string script) 
    Runspace MyRunspace = RunspaceFactory.CreateRunspace();
    Pipeline MyPipeline = MyRunspace.CreatePipeline(); 
    Collection<PSObject> outputs = MyPipeline.Invoke();
   StringBuilder sb = new StringBuilder(); 
   foreach (PSObject pobject in outputs) 
    return sb.ToString(); 

The RunScript() method creates first of all  a “runspace”.

Think it as an  isolated instance of the powershell runtime.

Then, we will add our script to the newly created pipeline, sort of communication channel,  and  execute our script commands via the Invoke() method.

Result will be appended to our string builder and returned as a string to our calling function for being displayed to console output. That’s why we added “Out-String” to our commands.

Very simple, do you agree?

Time to compile it and test it!

/out:c:\setup\powerless.exe c:\scripts\powersless.cs


Keep in mind that location may vary depending on the  framework versions installed on your system. Also remember to add  reference to the “” assembly.

If everything worked, you should have your compiled  powerless assembly. Create a simple test script:

echo "Hello from powershell-less"
echo "PID: $pid"

And launch it:



It worked! Just calling a script from our exe without powershell.exe!

This is a very simple script, things could be more complicated if you had to handle also user input and so on, but for the most part of activities where you need powershell this won’t be he case.

In next article we will try other tricks to bypass protections, stay tuned!

That’s all 😉



Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s