0

I have a bunch of powershell scripts, broken down to keep things modular. However, all or most of these scripts rely on certain common variables, like the server they talk to, etc. I'm defining these variable in the global scope and accessing them in the scripts using $global:{Variable} syntax.

This works fine in the script which serves as the entry point. However when the main (entry point) script executes a child script using the following syntax, I no longer can read the value of the same global variable. All I get is empty string.

Powershell.exe -File .\Child-Script.ps1

My understanding is:

  1. Parent scopes in powershell are inherited by child scopes
  2. Global scope should be available throughout all scripts getting executes in the current shell context.

What am I missing here? Please help.

Example:

Parent Script (Main-Script.ps1)

$global:ServerUrl="http://myserver.com"
Write-Host "ServerUrl (Main-Script): $global:ServerUrl"
Powershell.exe -File .\Child-Script.ps1

Child-Script (Child-Script.ps1)

Write-Host "ServerUrl (Child-Script): $global:ServerUrl"

Output

ServerUrl (Main-Script): http://myserver.com
ServerUrl (Child-Script): 
4
  • Please update your question with a very short sample script that illustrates the problem and give example outputs. Commented Jun 13, 2018 at 17:42
  • thank you for your response @Bill_Stewart. I added an example per your suggestion. Commented Jun 13, 2018 at 17:57
  • Powershell.exe -File .\Child-Script.ps1 tells powershell to run the script in a separate context. simply dot source the child script: . .\Child-Script.ps1 Commented Jun 13, 2018 at 18:05
  • Cool! that works! thank you @EBGreen. If you want to post this as an answer, I can mark it as the correct answer. Commented Jun 13, 2018 at 18:16

2 Answers 2

1

When you launch Powershell.exe you are creating a new powershell session with its own global context. So this:

Powershell.exe -File .\Child-Script.ps1

Will cause the child script to run in a different context. Instead you can 'Dot Source' the child script which will cause it to be executed in the current context:

. .\Child-Script.ps1
Sign up to request clarification or add additional context in comments.

Comments

0

Powershell.exe -File .\Child-Script.ps1 = Creates a new session with its own global scope indeed

. .\Child-Script.ps1 = it imports the script in the global scope of the current session . The script can then have access to the global scope but also the global scope to the script. So every function variable or class declared in the child class will be available in the global scope also.

Let's say that your Child-Script.ps1 contains the following line:

 $MyVar = "Hello"

And Parent-Script.ps1 :

 $MyVar = "GoodBye"
 # Dot Sourcing
 . .\Child-Script
 return $MyVar

In this example $MyVar will return "Hello" because the script was imported to the global scope , overriding it. This is useful for importing classes and functions into the global scope so that they are available in all scopes of the current session.

You Can even dot surce a function like so : . My-Func . By doing so , all the variables inside the function will be available in the global scope

In your example , just executing the script in its own scope is enough for this you just need to specify the full path or use the call operator ( & ) Like so:

 c:\path\to\Child-script.ps1  OR  .\Child-Script.ps1 ( Relative Path )

With ampersand (&) :

 & c:\path\to\Child-script.ps1  OR  & .\Child-Script.ps1

And if we now consider this as the new Parent-Script.ps1 :

 $MyVar = "GoodBye"
 # Call
 & .\Child-Script
 return $MyVar

In this case $MyVar will return "GoodBye"

Useful post : What is the difference between dot (.) and ampersand (&) in PowerShell?

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.