2

I've written a class which requires Powershell 5. Today I decided to test the class on the PC at work and... apparently:

The 'class' keyword is not supported in this version of the language

So now I'm in 2 mindsets. I could maybe change my script to import a C# class using Add-Type. However it got me thinking... As far as I know, Powershell, C#, VB.NET and all CLR programming languages all compile down to the Common Intermediate Language before they are actually run by the Common Language Runtime.

If this is the case, would it therefore be theoretically possible to compile my Powershell 5 class code to CIL, and then execute that code from Powershell 4? I know this is less maintainable, and would be a total hack, but I'd be interested in knowing how to do, if it were possible, regardless.

Sancarn
  • 2,575
  • 20
  • 45
  • Compiled PowerShell class will depend on PowerShell v5 engine features, which are not present in PowerShell v4 engine. – user4003407 May 06 '18 at 18:06

2 Answers2

2

Interesting one, Before I get to the Powershell just a quick overview

CLR is a run time that is used by many programming languages and what language you chose does not matter as long as the compiler you use targets the CLR

Besides Microsoft has created several language compilers that target the runtime, C++/CLI, C#, F# and so on

Process of Compiling source code to managed Modules

  1. Source code written in a language
  2. Gets compiled by its respective compiler (That targets CLR)
  3. You get a Managed Module(+metadata) which is Standard Windows portable executable 32bit (PE32) or (PE64) 64 bits

enter image description here

Combining Modules to Assemblies

The compiler then takes this Managed Module (IL+Metadata) and resource file and converts them to an Assembly

enter image description here

It is this Assembly(EXE/DLL) that the CLR makes use of for execution


As far as I know, Powershell, C#, VB.NET and all CLR programming languages all compile down to the Common Intermediate Language before they are actually run by the Common Language Runtime.

If this is the case, would it therefore be theoretically possible to compile my Powershell 5 class code to CIL,

With Powershell it works a bit different although it is based on the .NET Framework. It does not follow the same procedure as we saw in the previous example.

When you attempt to run a .ps1 script (Ver:3 and above)

  • It would first compile the parse tree to a LINQ

  • Which inturn gets converted to a byte code (CIL) which is then Intepreted (Just-In-Time)

  • Even at this stage this IL cannot be converted to Assemblies/DLLs/ in a reasonably straight forward manner(Not as far as I know).

But as a work around you can consider converting your Powershell script as an executable (PS2EXE) although it is not a very consistent approach.


References:

Link to PS2EXE :https://gallery.technet.microsoft.com/PS2EXE-Convert-PowerShell-9e4e07f1

Reference books : CLR via C#, Fourth Edition by Jeffrey Richter

https://www.safaribooksonline.com/library/view/clr-via-c/9780735668737/

Jason Shirk's answer: Does PowerShell compile scripts?

Clint
  • 6,011
  • 1
  • 21
  • 28
  • I guess each step of the Powershell execution process is inaccessible? I.E. Could I get the CIL and somehow execute that CIL from another Powershell version? – Sancarn May 06 '18 at 18:15
  • In a way, even if you manage to get hold of the CIL you will need disassemblers to examine it ? but what next ? You would somehow need to get to the DLL stage to be able get the CLR to execute its manifests ? – Clint May 06 '18 at 18:20
  • Right... Yeah xD I was hoping for a sort of `eval` for CIL... I did find [this](https://stackoverflow.com/a/26312107/6302131) which seems to somewhat evaluate the code, but not to the same degree as what I'd need... Will just have to re-write the classes I guess... xD – Sancarn May 06 '18 at 18:25
  • 1
    Unfortunately, `ps2exe` won't help. It just embeds the script source as an encoded _string_ into the executable wrapper. When you run the executable, it decodes the string and executes it. – Bruce Payette May 06 '18 at 18:32
1

The short answer is no - you can't do this. PowerShell generates IL internally but we don't support exporting it as a .dll. Jason's answer goes into more details on why we don't do that and why, even if you managed to extract the IL using the debugger, it still won't work.

Bruce Payette
  • 2,511
  • 10
  • 8