Search code examples
.netpowershellclrcil

Using a Powershell5 class in Powershell4 by compiling to CIL?


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.


Solution

  • 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?