When All Else Fails: PowerShell Reflective Assembly Loading
By Red Siege | April 9, 2026
by Ian Briley
Sometimes an older trick is the only trick that will work for you on an engagement.
Case in point, recently I was on an engagement, where if anything from my normal bag of tricks touched disk or looked dicey, AV/EDR would blow it away.
Loading raw PowerShell scripts from known attacker tooling got flagged and quarantined. Any encoded PowerShell scripts would get decoded and blown away.
Any binary, regardless of if a packer was used or not, got blocked by fairly strong application allowlisting processes.
The only thing I had access to was entering commands into the PowerShell terminal (even that had some restrictions in place). Often times the tests are time boxed to a week, and that’s not enough time to manually recreate and retype a binary’s functions into the command shell. I could not fathom trying to manually recreate tooling such as Certify in PowerShell without triggering an alert, especially in the limited amount of testing time I had.
Enter: PowerShell Reflective Assembly Loading!
In short, this is a technique you can use to load .NET assemblies into memory using PowerShell. There are a handful of caveats to this but effectively, since PowerShell is built directly on top of the newer versions of .NET, there’s a ton of overlap for C# classes. Which means for us there’s “minimal” tinkering to do this!
To make this work:
The first main part of this is making sure your access modifiers are set to public. This allows the current process you’re reflectively loading the binary into to access the code. Depending on your code this could be as easy as changing out a handful of access modifiers. Below is an example of this from the Certify repo.

Class Set to Public
Nothing special needs to be done to compile the code. Just compile the C# code how you’d normally do it. Next, we will want to convert our binary into bytes and then encode those bytes into base64 for safe transport. Never transfer raw bytes over the internet, it’s a recipe for disaster!
Typically, I save the encoded binary into a file so I can easily copy the encoded code out of that file and use elsewhere.
[Convert]::ToBase64String([IO.File]::ReadAllBytes("C:\SomeDirectory\DesiredBinary.exe")) | Out-File -Encoding ASCII C:\SomeDirectory\DesiredBinary.txt
Next, we’ll load the encoded binary into a variable in PowerShell.
$EncodedAssemblyName = [System.Reflection.Assembly]::Load([Convert]::FromBase64String("EncodedValueGoesHere"))
Finally, we’ll call on the program and point to its entry point (it’s always Main because C# enforces this standard).
[EncodedAssemblyName.Program]::Main("Any supporting arguments go here".Split())
In the Certify example, the program’s namespace is Certify, and the Main method is enclosed in the Program class. In this case, we can execute the code using convention below.
[EncodedAssemblyName.Program]::Main("Any supporting arguments go here".Split())
If your program’s namespace is different for some reason, or if the class isn’t Program, you’re going to need to make a few changes. Consider the following example pseudocode:
namespace MyNETAssembly
{
public class MyClass
{
public static void Main()
In this case, we’d execute the assembly like this:
[MyNetAssembly.MyClass]::Main("Any supporting arguments go here".Split())
This is a wonderfully easy way to get a binary that would not normally be allow-listed on the machine to run with all the functionality intact. Despite this being a fairly well documented technique with several detection signatures written for tools like Splunk or Elastic, I’ve rarely seen this actually trigger any alerts on the tests I’ve done.

Ian Briley has over 10 years of experience in information security consisting of The United States Armed Forces, the Healthcare industry, Security Operation Centers, and Security Consulting. Ian is an experienced presenter, trainer, developer, maker, and researcher. Ian enjoys attending local security focused groups and learning more about cloud-based environments and solutions
Certifications:
CRTO, GWAPT, eJPT, CySA+, SSCP, SEC+
Related Stories
View MoreBy Red Siege | September 3, 2026
by Justin Palk A couple of years ago, I put together a series on standing up a simple Windows AD domain in a lab environment. This article is part of […]
Learn MoreBy Red Siege | August 13, 2026
by Justin Palk A couple of years ago, I put together a series on standing up a simple Windows AD domain in a lab environment. This article is part of […]
Learn MoreBy Red Siege | July 7, 2026
by Justin Palk A couple of years ago, I put together a series on standing up a simple Windows AD domain in a lab environment. This is the start of […]
Learn More