Hi,
I have a script (script.ps1), in which a function is defined (func1). The script and function work fine, my problem is scoping.
‘func1’ needs to run in the current session. I can achieve that by dot sourcing script.ps1.
When func1runs, it makes calls via Invoke-Expression that need to set variable values (these variables are dynamic as they are pulled from command history, they aren’t defined in code within the func1 definition). The problem is, I need those variables to be set in the calling scope (i.e. the session that dot sourced script.ps1).
The only way I have found to make this work is by dot sourcing the func1 call in the current session after having dot sourced script.ps1. If i invoke func1 normally it doesn’t achieve the desired effect (as the variable assignments are trapped within the function scope of func1, and thrown away once the function completes).
Is there some way to set this up so that after dot sourcing script.ps1 (or a module version of the same), I can make it such that a normal, non-dot sourced invocation of func1 always occur in the calling scope just as if the call to func1 had been dot sourced?
(i.e. how do I make it so that ‘func1 -Arg1 $some_val’ operates as though that same call was dot sourced: ‘. func1 -Arg1 $some_val’)?
The first question is why you’re modifying variables outside the scope of func1? Why isn’t func1 returning the values to the caller and having the caller modify the values in its scope?
If you need to return multiple values, have func1 return a PSCustomObject, or pass func1 a reference to each of the variables in the callers’ scope, or pass func1 a reference to an empty hash and let func1 populate the hash.
Rather than relying solely on a textual description of the problem, why not provide a small example of the func1 code in the file script.ps1, a sample of how you’re using func1 (and script.ps1), and a variable of two in the base script that need modification.
3 Likes
This is a very good point, I think I was tunnel visioned on having the function execute the command from history (and somehow magically push the side effects to the calling scope as if the command had just been executed in the calling scope instead). Might be a lot easier to just pass the result back to the calling scope and have it ready for re-execution there. That is so obvious, yet somehow didn’t cross my thinking 
If you need to return multiple values, have func1 return a PSCustomObject, or pass func1 a reference to each of the variables in the callers’ scope, or pass func1 a reference to an empty hash and let func1 populate the hash.
