Powershell:将参数传递给存储在变量中的函数

时间:2012-08-04 00:08:07

标签: powershell powershell-jobs

我试图找到一个在作业中使用函数的简单工作示例。我已经设法将我的函数传递给用于我的工作的scriptblock,但我似乎无法获得该函数的参数。

# concurrency
$Logx = 
{
    param(
    [parameter(ValueFromPipeline=$true)]
    $msg
    )    
    Write-Host ("OUT:"+$msg)
}

# Execution starts here
cls
$colors = @("red","blue","green")
$colors | %{
    $scriptBlock = 
    {   
        Invoke-Expression -Command $args[1]
        Start-Sleep 3        
    } 

    Write-Host "Processing: " $_
    Start-Job -scriptblock $scriptBlock -args $_, $Logx
}

Get-Job

while(Get-Job -State "Running")
{
    write-host "Running..."
    Start-Sleep 2
}

# Output
Get-Job | Receive-Job

# Cleanup jobs
Remove-Job * 

这是输出:

Processing:  red
Id              Name            State      HasMoreData     Location             Command  
--              ----            -----      -----------     --------             -------  
175             Job175          Running    True            localhost               ...   
Processing:  blue
177             Job177          Running    True            localhost               ...   
Processing:  green
179             Job179          Running    True            localhost               ...   
179             Job179          Running    True            localhost               ...   
177             Job177          Running    True            localhost               ...   
175             Job175          Running    True            localhost               ...   
Running...
Running...
OUT:
OUT:
OUT:

所以OUT:x3在输出中证明我的函数被调用,但是我没有找到任何允许我获取函数参数的语法。想法?

编辑:

请注意下面Shawn的观察和我的回答我尝试使用函数作为变量,因为使用传统函数似乎不起作用。如果有办法让它工作,我会非常乐意不必将我的函数作为变量传递。

3 个答案:

答案 0 :(得分:3)

答案是使用Start-Job的initializationscript参数。如果您在块中定义所有函数并传递块,则它们可用。

在这篇文章中找到了解决方案:

How do I Start a job of a function i just defined?

这是我以前的例子,现在正在工作:

# concurrency
$func = {
    function Logx 
    {
        param(
        [parameter(ValueFromPipeline=$true)]
        $msg
        )    
        Write-Host ("OUT:"+$msg)
    }
}

# Execution starts here
cls
$colors = @("red","blue","green")
$colors | %{
    $scriptBlock = 
    {   
        Logx $args[0]
        Start-Sleep 9        
    } 

    Write-Host "Processing: " $_
    Start-Job -InitializationScript $func -scriptblock $scriptBlock -args $_
}

Get-Job

while(Get-Job -State "Running")
{
    write-host "Running..."
    Start-Sleep 2
}

# Output
Get-Job | Receive-Job

# Cleanup jobs
Remove-Job * 

答案 1 :(得分:0)

如果您没有在函数名前加上关键字function,则PowerShell不知道如何对其进行处理。在编写脚本时,它基本上是一个带有一些特殊文本的变量。您的输出显示它只执行它在该变量的内容中识别的命令:Write-Host "OUT:"

使用正确的语法将告诉PowerShell它是一个函数,并且您需要执行需要执行的变量:


function Logx
{
    param(
    [parameter(ValueFromPipeline=$true)]
    $msg
    )    
    Write-Host ("OUT:"+$msg)
}

然后,当您在脚本中调用它时,您将只使用Logx

答案 2 :(得分:0)

到目前为止。必须用完,稍后再试。 PS:args [1]传递了什么,我得到了很多红色,

 CategoryInfo          : InvalidData: (:) [Invoke-Expression], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.InvokeExpressionCommand

这是我迄今为止所管理的内容。

# concurrency
$Logx =
{
    param(
    [parameter(ValueFromPipeline=$true)]
    $msg
    )    
    Write-Host ("OUT:"+$msg)
}

# Execution starts here
cls
$colors = @("red","blue","green")
$colors | %{
    & $scriptBlock = 
    {   Invoke-Expression -Command $args[1]
        Start-Sleep 3  
    } 

    Write-Host "Processing: " $_
    Start-Job -scriptblock $scriptBlock -ArgumentList @($_, $Logx)
}

# Get-Job

while(Get-Job -State "Running")
{
    write-host "Running..."
    Start-Sleep 2
}

# Output
Get-Job | Receive-Job

# Cleanup jobs
Remove-Job *