Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does PowerShell compile scripts?

Suppose I have a simple PowerShell script:

1..3 | Write-Host 
  • How does PowerShell process it?
  • Does it build in-memory assembly or some temporary .dll file?
  • Can I examine this assembly and MSIL using some tools (e.g. ILSpy, VS, WinDbg)?
  • Does PowerShell treat processing of file scripts and REPL command line input the same way (i.e. both compiled / interpreted)?
  • Can I use this compiled assembly together with C# and other .Net languages?
  • Can the PS script be compiled to a native binary code?
like image 332
user2341923 Avatar asked Dec 10 '15 12:12

user2341923


People also ask

Is PowerShell interpreted or compiled?

Bottom line. To define PowerShell, it's an interpreted language, but this is a gray area when it comes to . NET.

How do PowerShell scripts work?

The PowerShell scripting language operates by executing a series of PowerShell commands (or a single one), with each command appearing on a separate line. For the text file to be treated as a PowerShell script, its filename needs to end in . PS1 to connote a PowerShell extension.

Are PowerShell scripts executable?

On Windows 10, to run a script file with the PowerShell console, you have to change the execution policy. To change the execution policy to run PowerShell scripts on Windows 10, use these steps: Open Start. Search for PowerShell, right-click the top result, and select the Run as administrator option.

Why do hackers use PowerShell?

PowerShell was used to carry out the critical piece of the attack. The PowerShell script was used to disable Windows Defender's antivirus prevention capabilities like real-time detection, script and file scanning and a host-based intrusion prevention system.


1 Answers

PowerShell V2 and earlier never compiled a script, it was always interpreted via virtual "eval" methods in the parse tree.

PowerShell V3 and later compile the parse tree (the AST) to a LINQ expression tree, which is then compiled to a bytecode, which is then interpreted.

If the script is executed 16 times, the script is JIT-compiled in the background, and as soon as the JIT compilation completes, the interpreted code will not be used. The same applies to loops: if a loop iterates 16 times, the loop body will be JIT-compiled and the loop body will switch from interpreted to JIT-compiled at the earliest possible time.

Many operations like accessing a member or invoking a C# method are always JIT-compiled in small dynamic methods. These dynamic sites are optimized for the dynamic nature of PowerShell, adapting to differing kinds of input on demand.

The JIT-compiled code is hosted in the "anonymous methods" assembly and cannot be saved. With WinDbg, you could disassemble the IL of the generated code.

Saving the compiled IL code as a DLL is not quite possible, because the generated code depends on live objects. It is technically possible for PowerShell to generate code that could be saved as a DLL, but that is not implemented.

Scripts and the REPL (interactive command prompt) work exactly the same.

Note that if PowerShell did actually generate an assembly, it would still require the version of PowerShell that compiled the script to be installed, you could not produce a fully portable exe.

It would be somewhat difficult and awkward to call PowerShell scripts from other languages because several factors - primarily pipelining and parameter binding - differ somewhat from normal method dispatch.

You can use objects returned from PowerShell scripts in C#. Starting in V3, if you use the dynamic keyword in C#, you can access properties, call script methods, etc. on a PSObject instance, just like you would on any other object. Before V3, you had to use an API like psobj.Properties['SomeProperty'].

like image 167
Jason Shirk Avatar answered Oct 04 '22 07:10

Jason Shirk