在 PowerShell 的模块中动态创建函数

Mik*_*ard 5 powershell module new-item

假设我在一个模块(称为 MyModule.psm1,在模块的适当位置)中有以下代码:

function new-function{

    $greeting='hello world'
    new-item -path function:\ -name write-greeting -value {write-output $greeting} -Options AllScope
    write-greeting
}
Run Code Online (Sandbox Code Playgroud)

导入模块并运行 new-function 后,我可以成功调用 write-greeting 函数(由 new-function 创建)。

当我尝试在 new-function 调用范围之外调用 write-greeting 函数时,它失败了,因为该函数不存在。

我试过 dot-sourcing 新功能,但这无济于事。我已经提供了-option Allscope, 但显然它只包含在子作用域中。

我还尝试使用 export-modulemember write-greeting 明确遵循 new-item 调用,该调用不会出错,但也不会创建函数。

我希望能够从模块内部的函数动态创建一个函数(即通过 new-item,因为函数的内容和名称将根据输入而变化),并使新创建的函数可用于在模块外部调用。

具体来说,我希望能够做到这一点:

Import-module MyModule
New-Function
write-greeting
Run Code Online (Sandbox Code Playgroud)

并看到“hello world”作为输出

有任何想法吗?

Roh*_*rds 7

使函数可见非常简单:只需在 New-Item 中更改函数的名称以具有global:作用域修饰符:

new-item -path function:\ -name global:write-greeting -value {write-output $greeting} #-Options AllScope
Run Code Online (Sandbox Code Playgroud)

但是,您的示例$greeting将遇到一个新问题,因为只会存在于new-function范围内,而在您调用write-greeting. 您正在使用未绑定的脚本块定义模块,这意味着它将$greeting在其范围内查找(它不会找到它),然后它将在任何父范围内查找。它不会看到来自 的那个new-function,因此您获得任何输出的唯一方法是模块或全局范围是否包含$greeting变量。

我不确定您真正的动态函数会是什么样子,但解决新问题的最简单方法是在您的脚本块周围创建一个新的闭包,如下所示:

new-item -path function:\ -name global:write-greeting -value {write-output $greeting}.GetNewClosure()
Run Code Online (Sandbox Code Playgroud)

这将创建一个新的动态模块,其中包含当时可用状态的副本。当然,这会产生一个新问题,即如果您调用Remove-Module MyModule. 没有更多信息,我不确定这对您是否有问题...