Add-Type

Like I mentioned before, Add-Type is a pretty powerful beast. The one-line description of "Adds a Microsoft .NET Core class to a PowerShell session." is deceptively simple, so we're going to dig a bit deeper here.

There are three major things you can do with Add-Type.

The documentation for Add-Type includes all the switches you could want, so it's a good resource to have on hand.

Loading an existing assembly

This is the most common thing to do. There is some functionality you need, but it's in an assembly that PowerShell hasn't loaded (yet!).

If there is an assembly installed in the GAC, you can load it with something like Add-Type -AssemblyName System.Web . If it's somewhere else, you should use the -Path parameter instead and pass the assembly file path.

Compiling your own classes

A little bit of code to encapsulate data and parse it or write it out in various ways is often handy. Here I'm just typing everything on the command-line. Note the @" syntax to start the string literal with quotes and double quotes embedded.

PS> $code = @"
>> public class MyRecord {
>>  public MyRecord(string value) {
>>   string[] parts = value.Split(new char[] { ',' });
>>   Name = parts[0];
>>   Age = System.Int32.Parse(parts[1]);
>>  }
>>  public string Name { get; set; }
>>  public int Age { get; set; }
>>  public override string ToString() { return Name + ", " + Age + " years old"; }
>> }
>> "@
PS> Add-Type -TypeDefinition $code
PS> $p = New-Object -TypeName MyRecord -ArgumentList "Marcelo,40"
PS> $p

Name    Age
----    ---
Marcelo  40


PS> $p.ToString()
Marcelo, 40 years old
PS>

Other cases where this is useful is when automating a process, where you want to control the input and output streams; .NET classes are quite reasonable to do that. Or perhaps you're reusing a snippet of code from somewhere else.

If things start getting a bit long, you can use the -Path argument, but refer to a .cs file rather than an assembly.

// save my to hello.cs
public class Greeter {
 public static void Greet() {
  System.Console.WriteLine("hello there");
 }
}

PS> Add-Type -Path hello.cs
PS> [Greeter]::Greet()
hello there

You will probably want to reference other assemblies sooner or later; the -ReferencedAssemblies switch will do the trick.

If things really get gnarly, consider having a regular pipeline build the code you care into assemblies, and then import the assembly, as per the above.

P/Invoking into native code

Actually, I'm not going to show an example of this, and here's why.

There are very, very few native APIs that you would want to call directly from a script; typically you have to manage resources and clean them up properly, and keep some state to interact with them. At this point, you're probably better off having some sort of proper encapsulation, and then a language like C# will serve you better - see the prior section on how to do that.

Happy typing!

Tags:  dotnetpowershell

Home