Run and compile .NET code in RES Workspace Manager (using PowerShell)

There are occasions where you need a custom solution to fulfill a requirement which cannot be solved with existing applications or tools. This is usually where scripting comes into the picture, nowadays we tend to built most scripts using Microsoft PowerShell as it’s a very powerful framework with a huge repository of cmdlets. Nonetheless there are situation where PowerShell has no built-in cmdlet (or third party cmdlet is available) and you’d have to revert to API’s or .NET code.

Wouldn’t it be a shame if you’d have to write and compile .NET code using an IDE like Visual Studio before you can use that code? Well, there’s a solution!

Common Intermediate Language

“Windows PowerShell is Microsoft’s task automation and configuration management framework, consisting of a command-line shell and associated scripting language built on the .NET Framework. Common Intermediate LanguagePowerShell provides full access to COM and WMI, enabling administrators to perform administrative tasks on both local and remote Windows systems as well as WS-Management and CIM enabling management of remote Linux systems and network devices.”  – Source: Wikipedia

While you’d probably already knew PowerShell is built on the .NET Framework and therefor compiles to common intermediate language (CIL) before being executed, just like all other .NET languages like Visual C++.NET, Visual C#.NET, VB.NET and more. As a result a PowerShell script that’s executed effectively  results in the same code as when it’s executed in C# or C++, one of the strengths of .NET.

 

 

Add-Type

In PowerShell, administrative tasks are generally performed by cmdlets (pronounced command-lets), which are specialized .NET classes implementing a particular operation. One of the more powerful cmdlets is Add-Type.

Adds a Microsoft .NET Framework type (a class) to a Windows PowerShell session.

So with the Add-Type cmdlet you can basically run any .NET code as long as you can define it in a .NET Framework class. And yes this includes API’s Smile . There are a number of parameters (all of which are optional) you can provide of which a few of them I’ll describe below for all other information: MSDN

For this article I’ll assume you want to run or compile code from the PowerShell script, not refer to an assembly stored elsewhere (although that’s possible). If you only want to run the code from the PowerShell script there’s no need to specify the output, but if you want you can using OutputType and OutputAssembly.

Parameter Description Example values
Language Specifies the language that is used in the source code – CSharp (default)
– CSharpVersion3
– VisualBasic
– JScript
CompilerParameters Specifies the options for the source code compiler. These options are sent to the compiler without revision. Options like /unsafe, for more options see MSDN
OutputType Specifies the output type of the output assembly – Library
– ConsoleApplication
– WindowsApplication

By default no output type is specified (the code is not compiled to an assembly)OutputAssemblyGenerates a DLL (or EXE) file for the assembly with the specified name in the location. Enter a path (optional) and file name. Wildcard characters are permitted TypeDefinition

OR

@Specifies the source code that contains the type definitions. Enter the source code in a string or here-string, or enter a variable that contains the source code. UsingNamespaceSpecifies other namespaces that are required for the class. This is much like the Using keyword in C#.All .available .NET namespaces, for instance System.IO

 

Example

Knowing which cmdlet can be used to run or compile .NET code how is this actually done? Let me show how in two examples. The first example will show you how to run .NET code that enables you to directly use an API in PowerShell, in the second example I’ll show you how to compile .NET code to a console application.

 

Example 1 – Run an API from a PowerShell script

In this example I’ll show you how you can call the SendMessage function (or API) directly from a PowerShell script. In the example I’ve placed C# code in a string $Win32_SendMessage which I’ll add using the Add-Type cmdlet so I can call it from PowerShell.

$Win32_SendMessage = @'
using System;
using System.Runtime.InteropServices;
    public static class Win32 {
    public static uint WM_CLOSE = 0x10;
    public static uint WM_DESTROY = 0x0002;

    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
    public static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);
}
'@

Add-Type -TypeDefinition $Win32_SendMessage

$p = @(Get-Process -Name Notepad)[0]
[Win32]::SendMessage($p.MainWindowHandle, [Win32]::WM_CLOSE, $zero, $zero) > $null

The script will close Notepad by sending a WM_CLOSE message to the process.

 

Example 2 – Compile c# code to a console application

In this example I’ll show you how to compile c# sharp code to a console application using PowerShell. The example  is the typical Hello World code from the a the C# Hello World Tutorial.

Add-Type -OutputType ConsoleApplication -OutputAssembly "HelloWorld.exe" @'
public class Hello1
{
   public static void Main()
   {
      System.Console.WriteLine("Hello, World!");
   }
}
'@

The output of the script is an console application called “HelloWorld.exe” which, when executed, prints “Hello, World!” on the screen.

 

RES Workspace Manager (optional)

Now you know how you can use PowerShell to run and compile all .NET code using PowerShell without having an IDE (like Visual Studio) let me show you how you do this using RES Workspace Manager. Depending on your needs you want to use RES Workspace Manager, or not.

The advantage of using RES Workspace Manager to run .NET code is timing and security,. You decide at what event (like user logon, network state change or when an application is launched – very powerful!) the code is executed from a managed environment. There’s no need to worry about if the script files are accessible or when someone’s changed it, that’s all available by default.

Command

RES Workspace Manager can execute commands to run applications tools or tools but can also run a script. When code is put in the script tab and %script% is used in the command line (or parameter) a temporary file with the provided extension is created on execution.

If RES Workspace Manager needs to execute a PowerShell script the following command line can be provided:

powershell.exe %script%

Personally I prefer to specify the full path and included parameters to set the execution policy, but his is optional:

%Windir%\System32\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy Bypass %Script%

Execute Command - PropertiesExecute Command - Script

 

Dynamic Privileges

Even better is the ability to execute a command (or a script) with administrative privileges even when the user hasn’t. This means that a regular user can execute a very powerful PowerShell script (calling API’s and stuff) with administrative privileges without granting this user with permissions it shouldn’t have. Dynamic Privileges are cool IMHO, especially since you can enable this feature on a specific action for an application or for the whole application.

Execute Command - Properties - Dynamic Priviliges

.

.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

en_USEnglish