Blair Conrad

expand your scope - you can dot-source more than just files

I'm working on a small project that will require me to dot-source some PowerShell files in order to load their functions, aliases, and variables and make them available in a session. Actually, I have to do a little more than dot-source each file, but I'll keep the example simple to illustrate the wrinkle I ran into.

Suppose I have this file, file-to-load.ps1:

Function Get-MyName
{
    Write-Output "Blair Conrad"
}

I dot-source it from the console, and everything's great:

PS> . .\file-to-load.ps1
PS> Get-MyName
Blair Conrad

Because I'll be doing this over and over, and I want to manipulate the .ps1 files a little more, I decide to wrap the dot-sourcing in a function, and call it.

Function Load-File([string] $filename)
{
    . $filename
}
PS> Load-File('.\file-to-load.ps1')
PS> Get-MyName
The term 'Get-MyName' is not recognized as the name of a cmdlet, function,
script file, or operable program. Check the spelling of the name, or if
a path was included, verify that the path is correct and try again.
At line:1 char:11
+ Get-MyName <<<<
    + CategoryInfo          : ObjectNotFound: (Get-MyName:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

Not good. The Get-MyName function is loaded inside the scope of the Load-File function. It's only available as long as I'm inside Load-File.

I thought about modifying all the script files that were to be loaded, scoping each contained function, alias, and variable as global, but that would be a pain, and I'm not going to be the only one writing these files. Eventually, I came upon it: dot-source the Load-File function:

PS> . Load-File('.\file-to-load.ps1')
PS> Get-MyName
Blair Conrad

I'll admit I don't quite understand why it works, but for now, I'm content to know that it does.