如何调用scriptblock之外的函数

时间:2017-09-18 08:47:41

标签: function powershell 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

我读了一些方法,但我不明白如何使用它们:
CALLING A POWERSHELL FUNCTION IN A START-JOB SCRIPT BLOCK WHEN IT’S DEFINED IN THE SAME SCRIPT

How to pass a named function as a parameter (scriptblock)

https://social.technet.microsoft.com/Forums/ie/en-US/485df2df-1577-4770-9db9-a9c5627dd04a/how-to-pass-a-function-to-a-scriptblock?forum=winserverpowershell

PowerShell: Pass function as a parameter

Using Invoke-Command -ScriptBlock on a function with arguments

我的剧本:

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

2 个答案:

答案 0 :(得分:2)

当您将脚本块传递给start-job(或invoke-expression)时,执行该脚本块的PowerShell实例只能访问该脚本块,脚本块加载的任何内容以及PowerShell中已存在的任何内容实例

不包含脚本的其他部分。 (对于脚本中本地定义的函数,可以从PowerShell的其他可能是远程的实例中获得整个脚本 - 而不仅仅是脚本块 - 并且需要从其他实例访问任何依赖项。)

您可以将两个地方所需的代码重构为脚本块加载的模块以及作业创建脚本。

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

答案 1 :(得分:0)

你可以这样做:

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中,然后从主脚本块中调用它。

希望它有所帮助。