19

From a PowerShell script, how can I determine if the script has been dot-sourced, i.e. it has been called with

. .\myscript.ps1

rather than

.\myscript.ps1

NOTE an interesting blog post (also) about this: http://poshoholic.com/2008/03/18/powershell-deep-dive-using-myinvocation-and-invoke-expression-to-support-dot-sourcing-and-direct-invocation-in-shared-powershell-scripts/

Paolo Tedesco
  • 55,237
  • 33
  • 144
  • 193

2 Answers2

20

To complement mjolinor's helpful answer:

tl;dr

$isDotSourced = $MyInvocation.InvocationName -eq '.' -or $MyInvocation.Line -eq ''

While $MyInvocation.InvocationName -eq '.' mostly tells you whether a given script is being dot-sourced, there is one exception:

When you run a script from the - obsolescent[1] - Windows PowerShell ISE with Debug > Run/Continue (F5), it is implicitly sourced, yet $MyInvocation.InvocationName contains the full script filename rather than . However, you can detect this case by checking if $MyInvocation.Line is empty.

(The PIC (PowerShell Integrated Console) that comes with Visual Studio Code's PowerShell extension used to behave this way, but as of at least version v2023.1.0 submits explicit dot-sourcing commands).

Note: Detecting whether a function is being dot-sourced is not subject to the exception above, so testing for $MyInvocation.InvocationName -eq '.' is sufficient (but the above will work too).


[1] The PowerShell ISE is no longer actively developed and there are reasons not to use it (bottom section), notably not being able to run PowerShell (Core) 7+. The actively developed, cross-platform editor that offers the best PowerShell development experience is Visual Studio Code with its PowerShell extension.

mklement0
  • 382,024
  • 64
  • 607
  • 775
  • 1
    Excellent, I spent way to much time determing this from LINE (due to all sorts of weird exceptions) and you guys have it simple and even this exception that I didn't know aobut. Thx – HerbM Mar 10 '18 at 21:27
17

Check $myinvocation.line It will show the line that was used to call the script.

 PS C:\scripts\test> gc test.ps1
 $myinvocation.line

 PS C:\scripts\test> ./test.ps1
 ./test.ps1

 PS C:\scripts\test> . ./test.ps1
 . ./test.ps1

You can also check the .invocationname property. If the script was dot-sourced, it will just be a dot. If not, is will be ./scriptname.ps1

mjolinor
  • 66,130
  • 7
  • 114
  • 135
  • 2
    Thanks, InvocationName was exactly what I was looking for. – Paolo Tedesco Feb 02 '11 at 15:47
  • The .Invocationname seems best, with "line" the first character might be a dot with relative path ..\test.ps1 when NOT dot surce, or when dot sourced the next character might not be a space. (parens, quotes, $( etc) Then add @mklement0 exception below. – HerbM Mar 10 '18 at 21:26
  • 1
    I think a better solution to check if script has been dot-sourced would be to check if `$MyInvocation.CommandOrigin -ieq 'Internal'`. But you do you. – Diti May 11 '22 at 20:30
  • 1
    @Diti, `$MyInvocation.CommandOrigin -eq 'Internal'` can yield _false positives_, such as with `& { ./script.ps1 }` – mklement0 Jan 28 '23 at 18:27