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.
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.
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.
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: dotnet powershell