将PowerShell函数添加到父作用域

时间:2011-04-26 15:35:37

标签: powershell powershell-v2.0

我在文件中有一些PowerShell辅助函数。我想让它们可用于我正在编写的另一个文件的范围,但不会污染全局范围。

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
    }
}

我发现了这个问题: How do I dynamically create functions that are accessible in a parent scope?但答案讨论了将功能添加到全局范围。我真正想做的是将Helper函数从一个PS1文件提供给调用的PS1文件,没有使用帮助程序污染全局范围。

我想避免将函数定义为变量,这可以通过Set-Variable和-Scope参数实现。我见过的最接近的(来自链接线程)在函数中使用Set-Item:drive。

任何帮助将不胜感激!

编辑:这是从Mike的回答扩展的解决方案

Helpers.ps1

function Helper
{
}

Utilities.ps1

&{
    function global:Utility
    {
        . ./Helpers.ps1
        Helper1
    }
}

使用点源语法加载Helpers.ps1将其内容放在Utility函数的范围内。将Helpers.ps1放在Utility函数之外会使它位于& {...}范围内,但是一旦定义了函数,该范围就会结束。

2 个答案:

答案 0 :(得分:6)

您可以在Utilities.ps1文件中使用此代码段。我们所做的就是获得所有当前的功能,然后我们点源助手。然后我们对前后函数进行区分。我们从diff中重新创建了全局范围内的函数。

$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) }"
}

答案 1 :(得分:5)

如果您在函数中点源.ps1文件,则ps1文件中的定义不是全局的,除非该函数本身是点源的。