Powershell: Using DLL classes in PowerShell (.psm1) module.

Created on 30 Jan 2020  路  6Comments  路  Source: PowerShell/PowerShell


I recently started porting some of my PowerShell code into C# modules. Currently I have a bunch of configuration classes that are used across quite a number of my PowerShell modules (currently stored in a classes modules and "imported" into each module via using module). My idea was the migrate all of the base classes I use for configurations into C# and implement them across C# and PowerShell modules. However I am hitting a snag in this process, it seems PowerShell modules don't seem to have visibility to classes in the compiled DLLs. I tried the using module syntax and also tried using Import-Module and the PowerShell module does not find the types.

If I go into the PowerShell console and do the following it works:

using module <DLL_MODULE_NAME>
Import-Module <POWERSHELL_MODULE_NAME>

Is this not the correct way to do this? Is a different way to create a class library I can share between PowerShell and C# code?

Steps to reproduce

Create a simple C# module (Some.Class.Module) with a single class inside.
Compile project, add DLL to PSModulePath
Create PowerShell module (psm1)
Add "using Some.Class.Module"  to the top of the file
Try to inherit or use the classes within the PowerShell module.

Expected behavior

Class is available within the module to be used/inherited.

Actual behavior

"Unable to find type" errors occur.

Environment data

Name                           Value
----                           -----
PSVersion                      6.2.4
PSEdition                      Core
GitCommitId                    6.2.4
OS                             Microsoft Windows 10.0.18362
Platform                       Win32NT
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0鈥
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0
Issue-Question

Most helpful comment

Using NestedModules is usually the recommended route, yeah. Ultimately any DLL imported will affect the entire PowerShell session regardless of where it's imported, so you can also just use Import-Module or Add-Type to import the module DLL from a PSM1 if you need that for some reason. 馃檪

All 6 comments

You could look BitLocker.psd1 on Windows.

NestedModules=@('Microsoft.BitLocker.Structures')

Thanks @iSazonov I figured I was missing something.

@iSazonov as a follow-up question, is this the proper way to include classes from a DLL/Cmdlet to a module's scope? And is using module intended to only be used on PowerShell (psm1) modules?

Using NestedModules is usually the recommended route, yeah. Ultimately any DLL imported will affect the entire PowerShell session regardless of where it's imported, so you can also just use Import-Module or Add-Type to import the module DLL from a PSM1 if you need that for some reason. 馃檪

@vexx32 just to be clear for documentation purposes, Import-Module also does not work, only using NestedModules fixes the issue. Import-Module and using module only worked on the DLL modules in the console, not within a module.

Out of curiosity, why does using module/Import-Module work on a DLL module within the console, but not within a PowerShell module? Is this meant to encourage using the NestedModules attribute or is it just weird behavior?

If I recall correctly, you should be able to Import-Module a DLL within a PSM1 file provided you also specify the cmdlet names in the module's CmdletsToExport manifest entry, but it's a been a little bit since I tinkered with it, so my memory could be out of date. 馃檪

Was this page helpful?
0 / 5 - 0 ratings

Related issues

pcgeek86 picture pcgeek86  路  3Comments

garegin16 picture garegin16  路  3Comments

manofspirit picture manofspirit  路  3Comments

Michal-Ziemba picture Michal-Ziemba  路  3Comments

SteveL-MSFT picture SteveL-MSFT  路  3Comments