Reputation: 103
I have a script I wish to use interactively from the PowerShell prompt. The script needs to use a local script module.
I cannot see how to import/use the module such that it's not left loaded in the current session.
Example
A module (MyModule.psm1)...
function Test-Method
{
write-host "Test-Method invoked"
}
... and a script (script.ps1)
Import-Module .\MyModule
Test-Method
Now running the script at the PowerShell prompt ...
PS C:\temp> Get-Module | % {$_.Name}
Microsoft.PowerShell.Management
Microsoft.PowerShell.Utility
PS C:\temp> .\script.ps1
Test-Method invoked
PS C:\temp> Get-Module | % {$_.Name}
Microsoft.PowerShell.Management
Microsoft.PowerShell.Utility
MyModule
How can my script import and use MyModule.psm1 without it being left loaded in the caller's current session? Bearing in mind that the call may have already imported the module and would not want it unloaded by the script (so simply removing the module at the completion of the script is not really good enough).
I've considered dot-sourcing the module rather than importing it, but I want the module for the reasons covered in PowerShell Import-Module vs Dot Sourcing
Upvotes: 9
Views: 29015
Reputation: 13964
This builds on the previous answer and uses the following property.
If you import a module from within another module, when the parent module is removed then any modules it imported will be removed
You can exploit several techniques to create a wrapper:
Set script.ps1 to
& (New-Module {
function Invoke-Function {
Import-Module .\MyModule
Test-Method
}
}) { Invoke-Function }
If you run script.ps1 and then (Get-Module).Name
then MyModule
will not be listed in the output.
Note: In this example Invoke-Function
is just another scope, and can be omitted, letting the New-Module
just run when defined. In one line:
& (New-Module { Import-Module .\MyModule; Test-Method }) {}
Upvotes: 3
Reputation: 3451
You can import the module with -Scope local
to restrict a module to your script's scope. If the module happens to also be loaded in the global scope, then it will still be available after your script exits.
Upvotes: -1
Reputation: 36768
It sounds like you already described in pseudo-code what you wanted. Here it is in actual code:
$checkCmds = Get-Commands -Module MyModule
Import-Module MyModule
# Do stuff here . . .
# unload only if we loaded it
if ($checkCmds -eq $null) { Remove-Module MyModule }
Upvotes: 8
Reputation: 202072
As far as I can tell, you don't get that automatic cleanup behavior from a "script" importing a module. OTOH if you import a module from within another module, when the parent module is removed then any modules it imported will be removed if there are no other modules using them (or unless ipmo -global was specified).
Upvotes: 1