How to detect whether a script is dot-sourced, or loaded as part of a module using powershell v2+?

Question:

Given a ps1 file as part of a module with the following code:

When loaded as part of the module, everything is fine. If I dot-source the script, I get

I know I could just add a -ErrorAction:Ignore on the Export-ModuleMember, but that’s not the point. I’d like to have a script run differently whether it has been imported, or dot-sourced.

In version 2, one could probably write a hack around the $PSScriptRoot, but that is just a hack, and doesn’t work in version 3 where they “fixed” $PSScriptRoot to never be null. I’ve tried looking at various items in $MyInvocation, but either I’ve missed something, or it has nothing useful.

I’ve also tried to run Get-Variable inside and outside a module, but again found no differences.

What have I missed that is different when running as Import-Module vs . myscript.ps1?

Answer:

It appears that I found the answer to this. I was missing something in $MyInvocation, because I was looking in the wrong scope. Given the following files:

.

.

and finally, make a symlink from the original ps1 to a psm1 with the correct name to load as a direct module.

The output shows that the parent scope has the key.

Output:

As we can see from the output shown (run on Server 2008 R2), the parent scope’s $MyInvocation.MyCommand contains the import module statement. I have not tested it yet, but I infer from this that if it’s multiple indirection through chained dot-sourcing, we can keep taking the parent scope until we get either Null or an Import-Module.

Now we know how to detect if we’re in a module or not, and through other resources can also grok if we’re being dot-sourced, executed directly, and/or loaded through a module.

Source:

How to detect whether a script is dot-sourced, or loaded as part of a module using powershell v2+? by licensed under CC BY-SA | With most appropriate answer!

Leave a Reply