19

I have an enum type defined within a module. How do I export it to be accessible from outside once the module has been loaded?

enum fruits {
 apple
 pie
}

function new-fruit {
    Param(
        [fruits]$myfruit
    )
    write-host $myfruit
}

My advanced function takes the enum instead of the ValidateSet which works if the enum is available, but fails if it isn't.

Update: Separating it into a ps1 and dot-sourcing it (ScriptsToProcess) works, however I would wish that there's a cleaner way.

JasonMArcher
  • 14,195
  • 22
  • 56
  • 52
Joel
  • 474
  • 1
  • 5
  • 15
  • 2
    See [how to export a class in powershell v5 module](//stackoverflow.com/a/38701492) - add `using module moduleName` after import – wOxxOm Oct 31 '16 at 23:50
  • 1
    @wOxxOm `The using module command imports the module and also loads the class definitions` https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_using?view=powershell-7.1#example-2---load-classes-from-a-script-module – metablaster Dec 17 '20 at 19:12

5 Answers5

15

Ran into the same issue trying to use/export an enumeration from a nested module (.psm1) on 5.0.x.

Managed to get it working by using Add-Type instead:

Add-Type @'
public enum fruits {
    apple,
    pie
}
'@

You should then be able to use

[fruits]::apple
Will
  • 340
  • 3
  • 8
  • 1
    +1 because this is the best method if you depend on module autoloading feature, otherwise we'd have to manually do `using module ...` – metablaster Dec 17 '20 at 19:29
10

You can access the enums after loading the module using the using module ... command.

For example:

MyModule.psm1

enum MyPriority {
    Low = 0
    Medium = 1
    high = 2
}
function Set-Priority {
  param(
    [Parameter(HelpMessage = 'Priority')] [MyPriority] $priority
  )
  Write-Host $Priority
}  
Export-ModuleMember -function Set-Priority

Make:

New-ModuleManifest MyModule.psd1 -RootModule 'MyModule.psm1' -FunctionsToExport '*' 

Then in Powershell...

Import-Module .\MyModule\MyModule.psd1
PS C:\Scripts\MyModule> [MyPriority] $p = [MyPriority ]::High
Unable to find type [MyPriority].
At line:1 char:1
+ [MyPriority] $p = [MyPriority ]::High
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (MyPriority:TypeName) [], RuntimeException
    + FullyQualifiedErrorId : TypeNotFound

PS C:\Scripts\MyModule> using module .\MyModule.psd1
PS C:\Scripts\MyModule> [MyPriority] $p = [MyPriority ]::High
PS C:\Scripts\MyModule> $p
high
Christopher G. Lewis
  • 4,777
  • 1
  • 27
  • 46
  • In short: `enum` and `class` definitions defined in PowerShell modules are only visible to importers of such modules if [`using module`](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_using#module-syntax) rather than [`Import-Module`](https://learn.microsoft.com/en-us/powershell/module/Microsoft.PowerShell.Core/Import-Module) is used. – mklement0 Jun 05 '23 at 15:20
  • Got it - thanks! – aksarben Jun 06 '23 at 21:28
2

When you get classes, enum or any .Net type in a module and you want to export them you have to use the using key word in the script where you want to import it, otherwise only cmlet are going to be imported.

Kingsley
  • 14,398
  • 5
  • 31
  • 53
1

I see your question said you were looking for a cleaner way than dot sourcing scripts or using the ScriptsToProcess, but this works for me.

Step 1:

  • Create a .PS1 file in your module. I called mine Enumerations.ps1, and placed the file in the root folder of my module.

  • In this new file place your enumeration statements

     ENUM DeathStarPlans {
         Reactor = 0
         Trench  = 1
         SuperSecretExhaustPort = 2
         }
    

Step 2

  • Update your .PSD1 manifest file to include the ScriptsToProcess option

  • Refer to the path to your enumeration file. This path is relative to where your .psd1 file is located.

     ScriptsToProcess = @(".\Enumerations.ps1")
    

Step 3

  • Import your module, this may require closing powershell and reopening if you have classes or other types created.

     Import-Module "module name" -force
    

Step 4

  • Use your enums

     [DeathStarPlans]::SuperSecretExhaustPort
    
Ro Yo Mi
  • 14,790
  • 5
  • 35
  • 43
-3

This looks to be an issue somewhere in the 5.0.x release of PowerShell.

I had the issue on 5.0.10105.0

However, this is working fine in the 5.1.x release.

Dustin
  • 39
  • 6