Reputation: 12653
I have some PowerShell helper functions in a file. I'd like to make them available to the scope of another file that I am writing, but not pollute the global scope.
Helpers.ps1
function global:Helper1
{
# this function pollutes the global scope
}
function Helper2
{
# this function is not visible to the Utility.ps1 file.
}
Utilities.ps1
&{
./Helpers.ps1
function global:Utility1
{
Helper1
}
function global:Utility2
{
Helper2
}
}
I found this question: How do I dynamically create functions that are accessible in a parent scope? but the answers discuss adding functions to the global scope. What I really want to do is make the Helper functions from one PS1 file available to a calling PS1 file, without polluting the global scope with the helpers.
I want to avoid defining the functions as variables, which is possible with Set-Variable and the -Scope parameter. The closest I've seen (from the linked thread) is using Set-Item in the function: drive.
Any help would be appreciated!
Edit: here is the solution expanded from Mike's answer
Helpers.ps1
function Helper
{
}
Utilities.ps1
&{
function global:Utility
{
. ./Helpers.ps1
Helper1
}
}
Using the dot-source syntax to load Helpers.ps1 puts it's contents in the scope of the Utility function. Putting Helpers.ps1 outside the Utility function causes it to be in the &{...} scope but that scope ends once the functions are defined.
Upvotes: 5
Views: 5767
Reputation: 1317
You can use this snippet in the Utilities.ps1 file. What we do is get all current functions then we dot source the helpers. We then make a diff of the before and after functions. From the diff we recreate the functions in the global scope.
$beforeFunctions = ls function:
. .\helpers.ps1
$afterFunctions = ls function:
$functionDiff = @(Compare-Object $beforeFunctions $afterFunctions)
foreach($diffEntry in $functionDiff){
$func = $diffEntry.InputObject
invoke-expression "function global:$($func.Name) { $($func.definition) }"
}
Upvotes: 7
Reputation: 18166
If you dot-source a .ps1 file in a function, the definitions that are in the ps1 file are not global, unless the function was itself dot-sourced.
Upvotes: 5