Suppose I have 2 files, A.ps1 and B.ps1, in this directory structure:
-- root
|
|-- A.ps1
|
|-- subfolder
|
|-- B.ps1
A.ps1:
Write-Host $PSScriptRoot
B.ps1:
. "\root\A.ps1"
Now, taking this fact into account:
Dot sourcing takes the script you've specified and immediately executes it as though it had been at that spot in your original script
THE PROBLEM: If I were to run B.ps1, I would expect the result to be \root\subfolder, but it's \root, why??
If A.ps1 is dot-sourced into B.ps1, shouldn't the contents of script A.ps1 run as if they were written directly inside of B.ps1? Meaning, shouldn't $PSScriptRoot run as if it was called from B.ps1, and thus evaluate to \root\subfolder? I've even tested this by wrapping A.ps1 in a function and calling that function in B.ps1 after dot-sourcing. Still yields the same result..
How does dot-sourcing really work?
As commenters noted,
$PSScriptRootis independent of scope. From the docs (emphasis mine):Dot-Sourcing doesn't literally "include" the script at the spot (contrary to the
#includedirective of C++, for instance), PowerShell still knows it is running a different script. The only thing that is different compared to calling the script (explicitly using the call operator&or running the script by entering its path), is the scoping.There is a way to get the
$PSScriptRootof the calling script though. Turn the script to be dot-sourced into an advanced function cmdlet by using theCmdletBinding()and/or theParameter()attribute. This makes the automatic variable$PSCmdletavailable, which gives you (amongst other things), the$PSScriptRootof the invoking script.A.ps1