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 Storage 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