Powershell: Type is not being imported script

Created on 19 Nov 2019  路  11Comments  路  Source: PowerShell/PowerShell

I have a custom module that contains a class and some functions using that type. I am able to use this module without issue, except in one single script. All the script does is import the module with a relative path and invokes a function from that module, but the function throws the error below, somehow not having access to the type even though the type is confirmed to be imported into the session. When I import the module into my session prior to running the script, there is no issue. When I try and simplify my script and module into the minimal repro steps described below, I am unable to repro. If someone messages me on Teams, I can show you our repos so you can repro; otherwise, please let me know of any further debug steps I can try and take to further isolate this weird bug.

Steps to reproduce

Read the paragraph above!

  1. Create a module MyModule.

    1. Create a script MyModule.Types.ps1 containing--

      powershell class MyType {}

    2. Create a file MyModule.psm1 containing--

      powershell function Show-MyType { Param([MyType]$MyVal) Write-Host $MyVal }

    3. Set in the module manifest

      powershell RootModule = 'MyModule.psm1' ScriptsToProcess = @( 'MyModule.Types.ps1' ) FunctionsToExport = @( 'New-MyType' )

  2. Create a script

    $ModulePath = "relative path to the module"
    Import-Module $ModulePath
    
    $myVal = [MyType]::new()
    Show-MyType $myVal
    

Expected behavior

The script runs without error.

Actual behavior

Throws

Show-MyType : Unable to find type [Cluster].

Environment data


Name                           Value
----                           -----
PSVersion                      6.2.3
PSEdition                      Core
GitCommitId                    6.2.3
OS                             Microsoft Windows 10.0.18363 
Platform                       Win32NT
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0螕脟陋}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0

Issue-Question Resolution-Answered

All 11 comments

@chriskuech out of curiosity, is the offending type in your actual module an attribute?

It's due to using ScriptsToProcess to try to get around class import issues. The import script runs in the current scope of the global session state. That scope will be your script. Once that script finishes, the class goes out of scope. That's why if you follow your repro exactly, it'll work once. The ScriptsToProcess will only fire when actually importing the module, if the module is already in the session then nothing happens. Try the using module method instead.

The ScriptsToProcess will only fire when actually importing the module, if the module is already in the session then nothing happens.

This problematic behavior is the subject of #9582.

@vexx32 - it's not an attribute

@SeeminglyScience , @mklement0 - I don't think that is the behavior I am describing. In my simplified repro I can run it as many times as I want because the type is already defined in scope, whereas I can't even run it once in my actual code. This seems to be mitigated if I dot-source my ScriptsToProcess script in my module.

Does PowerShell team have plans or a GitHub issue to switch over to an import system more like Python or TypeScript?

@SeeminglyScience , @mklement0 - I don't think that is the behavior I am describing. In my simplified repro I can run it as many times as I want because the type is already defined in scope, whereas I can't even run it once in my actual code. This seems to be mitigated if I dot-source my ScriptsToProcess script in my module.

The repro in your original message works? If that's not what you're referring to, if you provide the code you're working with I can tell you why it does or does not work.

Does PowerShell team have plans or a GitHub issue to switch over to an import system more like Python or TypeScript?

Have you tried using module? I think that's about as similar as PowerShell can reasonably achieve (excluding bugs).

using module does seem to work (didn't realize it would work with ScriptsToProcess. It's not ideal though, because using module only works with relative paths, so my script is now coupled to being run from a single location.

using module works for any module you have installed / available on $env:PSModulePath as far as I'm aware? 馃

Ya it's not in $env:PSModulePath. Future work to take on but would currently break things.

using module does seem to work (didn't realize it would work with ScriptsToProcess. It's not ideal though, because using module only works with relative paths, so my script is now coupled to being run from a single location.

With ScriptstoProcess? The idea would be to use it instead of ScriptsToProcess. You'd put the classes in your psm1 and use using module in the scripts that utilize the classes. The whole ScriptsToProcess thing with classes is something someone came up with as a hack to get around scoping issues, but really it just moves them around and makes it less predictable. But if it works, it works 馃し鈥嶁檪

This issue has been marked as answered and has not had any activity for 1 day. It has been closed for housekeeping purposes.

Was this page helpful?
0 / 5 - 0 ratings