3

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

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

在下面的示例中,我有一个getNumberFive应该返回数字 5的函数。
我希望能够在我开始一项新工作时以及在脚本结束时在脚本块中使用这个函数。

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

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

我可以通过在脚本块中定义相同的函数来解决这个问题,但是我将复制该函数,这不是一个好的编程。

另一种方法是定义:

$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 它在同一个脚本中定义

如何将命名函数作为参数传递(脚本块)

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:将函数作为参数传递

在带参数的函数上使用 Invoke-Command -ScriptBlock

我的脚本:

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
4

2 回答 2

4

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

不包括脚本的其他部分。(为了使脚本中本地定义的函数可以从其他(可能是远程的)PowerShell 实例中使用,整个脚本——不仅仅是脚本块——以及任何依赖项都需要可以从其他实例访问。)

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

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

于 2017-09-18T08:58:14.583 回答
1

你可以这样做:

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,您可以在其中将初始化代码保留为函数。将它包装在一个脚本块中,然后从主脚本块中简单地调用它。

希望能帮助到你。

于 2017-09-18T09:09:44.577 回答