Function 如何在脚本块外调用函数

Function 如何在脚本块外调用函数,function,powershell,scriptblock,Function,Powershell,Scriptblock,我有一个函数,我应该能够从powershell脚本中的任何位置调用它 问题是它不能识别脚本块中的函数 在下面的示例中,我有一个函数getNumberFive,它应该返回数字5。 我希望在启动新作业时以及脚本结束时,能够在脚本块内使用此函数 预期结果: 将编号15写入文件“C:\tmp\result.txt” 写信给控制台:“我喜欢数字5” 事实上: 将编号10写入文件“C:\tmp\result.txt” 写信给控制台:“我喜欢数字5” 我可以通过在scriptblock中定义相同的函数来解决这

我有一个函数,我应该能够从powershell脚本中的任何位置调用它

问题是它不能识别脚本块中的函数

在下面的示例中,我有一个函数
getNumberFive
,它应该返回数字5。
我希望在启动新作业时以及脚本结束时,能够在脚本块内使用此函数

预期结果:
将编号15写入文件“C:\tmp\result.txt”
写信给控制台:“我喜欢数字5”

事实上:
将编号10写入文件“C:\tmp\result.txt”
写信给控制台:“我喜欢数字5”

我可以通过在scriptblock中定义相同的函数来解决这个问题,但是我会复制这个函数,这不是一个好的编程

另一种方法是定义:

$func = {
    function getNumberFive(){
        return 5
    }
}
$scriptBlock = {

    Function printSum(){
        $number = getNumberFive
        $newNumber = 10 + $number  # => $newNumber should be 15
        $newNumber >> "C:\tmp\result.txt"
      }
}
Start-Job -ScriptBlock $scriptBlock -InitializationScript $func
但在这种情况下,我将无法调用
$five=getNumberFive

我读了很多方法,但不知道如何准确地使用它们:

我的剧本:

function getNumberFive(){
    return 5
}

$scriptBlock = {

    Function printSum(){
        # $number = getNumberFive => DOESN'T WORK
        # $number = Invoke-Expression ($(get-command getNumberFive) | Select -ExpandProperty Definition) => DOESN'T WORK AS EXPECTED
        # $number = &(${function:getNumberFive}) => DOESN'T WORK AS EXPECTED
        # $number = &(Get-Item function:getNumberFive) => DOESN'T WORK AS EXPECTED
        $newNumber = 10 + $number  # => $newNumber should be 15
        $newNumber >> "C:\tmp\result.txt"
    }

    printSum
}

Start-Job -ScriptBlock $scriptBlock 

$five = getNumberFive
Write-Host "I like the number"$five

Get-Job | Wait-Job
Get-Job | Stop-Job
Get-Job | Remove-Job

将scriptblock传递给
启动作业
(或
调用表达式
)时,执行该scriptblock的PowerShell实例只能访问该scriptblock、脚本块加载的任何内容以及PowerShell实例中已存在的任何内容

脚本的其他部分不包括在内。(要使脚本中本地定义的函数可以从PowerShell的其他(可能是远程)实例访问,需要从其他实例访问整个脚本(而不仅仅是scriptblock)和任何依赖项。)

您可以将这两个位置的代码重构为脚本块加载的模块以及作业创建脚本

使用作业时,您正在另一个进程中执行代码:与任何远程操作一样,远程执行是一个单独的环境。

您可以这样做:

function getNumberFive(){
    return 5
}

$a={
Function printSum($number){
        $newNumber = 10 + $number  # => $newNumber should be 15
        $newNumber >> "D:\result.txt"
    }
}

$scriptBlock = {
param($number)
    printSum -number $number
}
$five = getNumberFive
Write-Host "I like the number"$five

Start-Job -InitializationScript $a -ScriptBlock $scriptBlock -ArgumentList $five
在Start job中有一个开关名-InitializationScript,您可以将初始化代码保存为函数。将其包装在scriptblock中,只需从主scriptblock调用它


希望有帮助。

我想要这样的东西,但是行
$five=getNumberFive
对我不起作用。@E235:根据你的评论。我已经编辑了答案。你也必须编译这个函数。我运行了它,但它仍然不能工作。它打印到控制台
我喜欢数字5
,但它不会将总和15写入文件。您还忘了在
$initialization\u block
中取消注释
$number=getNumberFive
。我在取消注释后进行了检查。这段代码是我创建的一段非常简单的代码,目的是让事情变得足够简单,让人们能够理解我。真正的代码更复杂。在实际代码中,我确实需要使用
start job
。我在问题中提到,预期结果是将15写入一个文件,并将“我喜欢数字5”写入一个控制台。你的建议不会发生这种情况。这是可行的,但我需要找到一种从代码中的任何地方调用函数的方法。您使用的是
getNumberFive
结果,因为您知道它是常量。在其他情况下,它可以是检查脚本块内部特定内容的函数。我现在没有好的榜样,因为我想让事情变得简单。我将查找并向您展示它不起作用的案例。请尝试
-InitializationScript$function:getNumberFive
@TheIncorrigible1它不起作用。我也试过了,在我的问题中,在单独的脚本块中声明了
getNumberFive
,但是
我喜欢数字5
不起作用。