Is there any way for a powershell module to get at its caller’s scope?

Question:

I have a collection of utility functions and other code that I dot-source into every powershell file I write. Having gotten bit by caller scope variables influencing it, I started looking into changing it into a powershell module.

I ran into problems with a couple of the special things I do in it where I actually do want some interaction between the scopes. I’m wondering if there is anyway to “get at” the scope of a module’s caller to keep this functionality while moving to a powershell module?

If not, is my best path forward to keep these more specialized things in a dot-sourced file and move the more traditional utility functions into a module? Here are the things that don’t easily move to a module:

  • Setting strict mode and error action preferences to keep sane, e.g.:

    This (as expected) has no effect on the caller’s environment when the code is run from a .psm1 powershell module. Is there any way to cross from the psm1 scope to the caller scope to make these changes?
  • Printing out information about the top-level script call, e.g.:

    Likewise, these commands can no longer see the top-most calling scope once placed in a .psm1 file

Answer:

$PSCmdlet.SessionState seems to provide a function inside a script module access to the call site’s variables provided the call site is outside the module. (If the call site is inside the module, you can just use Get- and Set-Variable -Scope.) Here is an example using SessionState:

which outputs

I’m not sure whether SessionState was intended to be used in this manner. For what it’s worth, this is the same technique used in Get-CallerPreference.ps1. There are also some test cases here which pass on PowerShell versions 2 through 5.1.

Source:

Is there any way for a powershell module to get at its caller’s scope? by licensed under CC BY-SA | With most appropriate answer!

Leave a Reply