fbpx Program: Add Inline C# to Your PowerShell Script | Windows PowerShell, Windows Server | HostingUltraso.com
24/7/365 Support

Program: Add Inline C# to Your PowerShell Script

One of the natural languages to explore after learning PowerShell is C#. It uses many of the same programming techniques as PowerShell and uses the same classes and methods in the .NET Framework as PowerShell does, too. In addition, C# sometimes offers language features or performance benefits not available through PowerShell.

Rather than having to move to C# completely for these situations, Example 158 lets you write and invoke C# directly in your script.

Example 158. InvokeInline.ps1

################################################################################

## InvokeInline.ps1

## Library support for inline C#

##

## Usage

## 1) Define just the body of a C# method, and store it in a string. "Here

## strings" work great for this. The code can be simple:

##

## $codeToRun = "Console.WriteLine(Math.Sqrt(337));"

##

## or more complex:

##

## $codeToRun = @"

## string firstArg = (string) ((System.Collections.ArrayList) arg)[0];

## int secondArg = (int) ((System.Collections.ArrayList) arg)[1];

##

## Console.WriteLine("Hello {0} {1}", firstArg, secondArg );

##

## returnValue = secondArg * 3;

## "@

##

## 2) (Optionally) Pack any arguments to your function into a single object.

## This single object should be stronglytyped, so that PowerShell does

## not treat it as a PsObject.

## An ArrayList works great for multiple elements. If you have only one

## argument, you can pass it directly.

##

## [System.Collections.ArrayList] $arguments =

## NewObject System.Collections.ArrayList

## [void] $arguments.Add("World")

## [void] $arguments.Add(337)

##

## 3) Invoke the inline code, optionally retrieving the return value. You can

## set the return value in your inline code by assigning it to the

## "returnValue" variable as shown above.

##

## $result = InvokeInline $codeToRun $arguments

##

##

## If your code is simple enough, you can even do this entirely inline:

##

## InvokeInline "Console.WriteLine(Math.Pow(337,2));"

##

################################################################################

param( [string] $code = $(throw "Please specify the code to invoke"), [object] $arg, [string[]] $reference = @() )

## Stores a cache of generated inline objects. If this library is dotsourced ## from a script, these objects go away when the script exits.

Example 158. InvokeInline.ps1 (continued)

if(not (TestPath Variable:\Lee.Holmes.inlineCache)) { ${GLOBAL:Lee.Holmes.inlineCache} = @{} }

## The main function to execute inline C#. ## Pass the argument to the function as a stronglytyped variable. They will ## be available from C# code as the Object variable, "arg". ## Any values assigned to the "returnValue" object by the C# code will be ## returned to the caller as a return value.

function main

{ ## See if the code has already been compiled and cached $cachedObject = ${Lee.Holmes.inlineCache}[$code]

## The code has not been compiled or cached if($cachedObject eq $null) {

$codeToCompile = @" using System;

public class InlineRunner

{ public Object Invoke(Object arg) {

Object returnValue = null;

$code

return returnValue; } } "@

## Obtains an ICodeCompiler from a CodeDomProvider class. $provider = NewObject Microsoft.CSharp.CSharpCodeProvider

## Get the location for System.Management.Automation DLL $dllName = [PsObject].Assembly.Location

## Configure the compiler parameters $compilerParameters = NewObject System.CodeDom.Compiler.CompilerParameters

$assemblies = @("System.dll", $dllName) $compilerParameters.ReferencedAssemblies.AddRange($assemblies) $compilerParameters.ReferencedAssemblies.AddRange($reference) $compilerParameters.IncludeDebugInformation = $true $compilerParameters.GenerateInMemory = $true

## Invokes compilation.

Example 158. InvokeInline.ps1 (continued)

$compilerResults = $provider.CompileAssemblyFromSource($compilerParameters, $codeToCompile)

## Write any errors if generated. if($compilerResults.Errors.Count gt 0) {

$errorLines = "`n$codeToCompile" foreach($error in $compilerResults.Errors) {

$errorLines += "`n`t" + $error.Line + ":`t" + $error.ErrorText } WriteError $errorLines

} ## There were no errors. Store the resulting object in the object " ## cache. else {

${Lee.Holmes.inlineCache}[$code] = $compilerResults.CompiledAssembly.CreateInstance("InlineRunner") }

$cachedObject = ${Lee.Holmes.inlineCache}[$code] }

## Finally invoke the C# code if($cachedObject ne $null) {

return $cachedObject.Invoke($arg) } }

. Main

Help Category:

Get Windows Dedicated Server

Only reading will not help you, you have to practice it! So get it now.

Processor RAM Hard Drive Server Detail
Intel Atom C2350 1.7 GHz 2c/2t 4 GB DDR3 1× 1 TB (HDD SATA) Configure Server
Intel Atom C2350 1.7 GHz 2c/2t 4 GB DDR3 1× 128 GB (SSD SATA) Configure Server
Intel Atom C2750 2.4 GHz 8c/8t 8 GB DDR3 1× 1 TB (HDD SATA) Configure Server
Intel Xeon E3-1230 v2 3.3 GHz 4c/8t 16 GB DDR3 1× 256 GB (SSD SATA) Configure Server
Intel Atom C2350 1.7 GHz 2c/2t 4 GB DDR3 1× 250 GB (SSD SATA) Configure Server

What Our Clients Say