Reputation: 1144
I have a class in the PowerShell module file. (A.psm1
)
class A {
[void] printString() {
write-host 111
}
}
And I also have a simple script that uses that class.
Using module C:\temp\A.psm1
$a = [A]::new()
$a.printString() # prints 111
But if I change the method from the class, for example, as shown here (replace 111
on 222
)
[void] printString() {
write-host 222
}
and if I relaunch my script it will still print 111
. Only if I restart the PowerShell console it will print the new value.
If I worked only in the console, I could use the Import-Module ... -Force
command. But it doesn't work in the script.
So is there a way to reload the PowerShell module every time the script is launched without restarting the console itself?
Upvotes: 5
Views: 2867
Reputation: 438208
As far as I know, there's no good solution, unfortunately (as of PowerShell 7.2): The using module
statement - which is the prerequisite for also loading class
es from a module - has no equivalent to the Import-Module
's -Force
switch for forcing reloading of a module.
Workaround:
# (Force-re)load the module and get a reference to the module.
# This does NOT give you access to the classes defined in the module.
$module = Import-Module C:\temp\A.psm1 -PassThru -Force
# Use the module reference to execute code *in the module's* context,
# where the class *is* defined, so you can obtain a reference to the
# [A] class (type) this way:
$classA = & $module { [A] }
$classA::new().printString()
As you can see, this requires modifying the source code.
If you're using Visual Studio Code with the PowerShell extension, you can avoid this, as shown in Mathias R. Jessen's helpful answer.
Upvotes: 4
Reputation: 174545
This unfortunate behavior is a well-known issue, and as mklement0 points out no real good solution exist at the moment.
The underlying cause is a bit convoluted (part of the reason the behavior persists after 5+ years), but it's basically a 3-way conflict between:
using module
provides parse-time resolution of custom types - its not a particularly mature feature to put it plainlyAlthough no good solution exists, the VSCode PowerShell extension has a configuration option allowing you to run debug sessions in a temporary shell, making it a non-issue:
{
"powershell.debugging.createTemporaryIntegratedConsole": true
}
Once set, you can use the following workflow for testing/debugging:
Shift+Ctrl+D
-> Run and Debug
)printString()
prints 111
printString()
now prints the new valueUpvotes: 7