In my Powershell "project" I would like to have all the common Enum's in a single file and then reference that file from the various other scripts.
I've tried dot-sourcing the file, and I tried converting the Enum file to a psm1 (Import-Module), but nothing I've tried so far has worked.
For example, the Enum file datatypes.ps1 looks something like this:
Enum DataType { String, Integer, Boolean }
And I tried to include it like this:
. ".\datatypes.ps1"
class MyClass {
[DataType]$Type = [DataType]::String
}
When I run the above I get the error message:
Unable to find type [DataType].
I've used dot-sourcing to include variables and functions before, those have always worked. But now the Enum's are refusing to work :(
Should dot-sourcing work? Should the module approach work? or must Enum's be located in the same file/script?
EDIT:
I think I might have found the problem, it seems that the script is being completely parsed before the include is being included, is that possibly the issue?
I believe Import-Module does not work, because it loads items in to a different context. You can use the dot sourcing or the using module
statement. If you are using the latter, then you need to provide a fully path to the file or place it in one of the $env:PSModulePath
paths.
If you want to import enums or classes in to a module I find the approach below works best, i.e. dot sourcing the full filenames in the module psm1 file.
Assuming a basic project layout like:
- MyModule
|- Classes
|- MyClasses.ps1
|- Enums
|- MyEnums.ps1
|- MyModule.psm1
|- MyModule.psd1
if (Test-Path -Path "$PSScriptRoot\Classes") {
$Enums = Get-ChildItem (Join-Path $PSScriptRoot Enums) -Filter *.ps1 -ErrorAction SilentlyContinue
$Classes = Get-ChildItem (Join-Path $PSScriptRoot Classes) -Filter *.ps1 -ErrorAction SilentlyContinue
# Order imports so that Enums are before Classes
foreach ($Class in @($Enums;$Classes)) {
Try {
. $Class.FullName
Write-Verbose -Message "Imported $($Class.BaseName)"
}
Catch {
Write-Error -Message "Could not load Class [$($Class.Name)] : $($_.Message)"
}
}
}
# Import functions here if you have them, or do anything else.