Recently, while working in PowerShell, I had the need to understand PowerShell scope — the details of which you can peruse in about_Scopes. I found it a fascinating read — one you’ll come back to often.
Towards the bottom of the doc, you’ll see a discussion headed “Using Dot Source Notation with Scope”. It describes the (in)famous PowerShell “dot source” or “dot sourcing” way of executing PowerShell scripts. I found the explanation there very difficult to understand at first. Then I came across Jeff Wouter’s explanation of dot sourcing which almost solidified my understanding. But there’s an assumption in both the documentation and among PowerShell users about how PowerShell is being used that, when made explicit, makes all the pieces fall into place.
PowerShell is…well…a shell. I’m often unconscious of this as I work primarily in Sapien’s PowerShell Studio, a very powerful integrated development environment for PowerShell. When you work with PowerShell this way, you can forget (and I often do) that it’s not a compiled programming language, but an interactive shell.
But when you remember that PowerShell was intended to replace the venerable Windows shell (
cmd.exe), the need to manage scope in that interactive shell is apparent.
That’s what PowerShell dot sourcing does. Boiled down to its essence, a saved script you run in the shell (as opposed to cmdlets entered interactively in that shell) does not share its scope with the shell. But suppose that’s exactly the behavior you want? Suppose you want to load up a bunch of aliases or variables into the interactive shell? How can you do that? Simple: you dot source the PowerShell script which then adds variables in that script to the shell’s scope. There is, of course, much more to this (see the documentation).
The point of this post is to make clear the distinction between the PowerShell shell as an interactive command environment containing variables with their own scope and the PowerShell command environment as a way to run scripts which may or may not share their contents’ scope with the shell.
A picture is worth a thousand words. Consider this simplest of all PowerShell scripts, which creates a string variable:
There’s nothing to it, right? Running this script outputs nothing. But while it was running, there was a string variable created whose scope was limited to the duration of the script’s execution.
Now consider this interactive PowerShell session. First, we attempt to output the contents of a string variable with the same name as the variable in the script. As expected, there isn’t one. Then, we dot-source the script which runs, producing no output. But this time, when we output the variable, it produces the string that was assigned to it from within the script that was dot-sourced.
The bottom line is simple: the shell’s and script’s scopes are separate, until you share them by using PowerShell dot sourcing.