5

I'm using PowerShell 5.1, Windows 10 x64.

Which of these 2 cmdlets should I use to load .NET assemblies (in particular .NET Framework 4+ assemblies) into PowerShell? What's the core difference between them? I want to load assemblies for accessing types, creating objects, calling methods, etc.

I haven't found any explicit statements in the documentation. These cmdlets are described like they are completely different things. MSDN documentation for Import-Module doesn't even contain examples for .dll assemblies loading -- only PowerShell modules. However Import-Module works with .NET Framework assemblies (.dll only, though): I can perfectly work with types from the imported assemblies, their referenced assemblies are resolved and loaded too. Why is that?

In other words, from my experience I haven't yet found any differences between these 2 assemblies importing methods (at least for .NET Framework 4 .dll assemblies).

This old blog post: Using .NET Framework Assemblies in Windows PowerShell even uses Reflection.Assembly.LoadWithPartialName! I believe this is because they load an assembly from the GAC and do not want to specify full path to it (I may be wrong, though).

For my assemblies I know full path to them, so I can specify it in both Import-Module and Add-Type. Again, what's the difference and what should I use?

Thanks!

1 Answer 1

8

Powershell has three main ways to import classes, not counting .net methods like reflection.assembly. In general, all of them will do what you need just fine, but have extra features:

Import-Module

has by far the most flexibility, and can import basic Modules (usually .psd1 or .psm1 files) and their required assemblies, CIM Modules (with CDXML files), [Assembly]-type objects, assemblies via .dll files, cmdlets via .dll files, and probably more. There's more features for importing PS Modules, but not for classes other than "load the whole thing".

Add-Type

has a bunch of extra functionality for adding classes efficiently if you need it. For example, it can take C#/VB/JScript type definitions as string and load them directly. I personally only use it when I need that, or if a dll file can't be imported correctly by import-module, but there are many more features listed on the help. It doesn't import modules like the other options.

Using

Relatively new and only in v5.1+. It will import class definitions from a module, unlike Import-Module or the #requires statement. Otherwise, it behaves very similarly to ipmo, but I like it for its readability and much prefer using namespace to the .net version:

using module ModuleName
# or
using assembly 'C:\path\to\assembly.name.subassembly.whatever.dll'
using namespace assembly.name.subassembly.whatever.additional.namespace

[NiceAndShort]::Foo

their referenced assemblies are resolved and loaded too. Why is that?

Unfortunately, powershell takes the path of simply loading every assembly (and their dependencies, and powershell's own dependencies) into the same context. This can cause some headaches when dealing with conflicting dependency versions. It's better covered in Resolving PowerShell module assembly dependency conflicts.

1
  • Thanks, I didn't even know about <using>. I'm familiar with basic PowerShell concepts, but I'm always learning something new :) Commented Aug 27, 2021 at 21:10

Not the answer you're looking for? Browse other questions tagged or ask your own question.