Powershell: передача параметров функциям, хранящимся в переменных

Я пытаюсь получить простой рабочий пример использования функций внутри рабочих мест. Мне удалось передать свою функцию в блок скриптов, используемый для моей работы, но я не могу получить параметры для функции.

# 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 в выводе, вызывается моя функция, но я не нашел никакого синтаксиса, который позволил бы мне получить параметр для функции. Мысли?

РЕДАКТИРОВАТЬ:

Обратите внимание на наблюдение Шона ниже и мой ответ. Я пытался использовать функции в качестве переменных, потому что использование традиционной функции, похоже, не работает. Если есть способ заставить это работать, я был бы более чем рад, если бы не передавал свои функции как переменные.

3 ответа

Решение

Ответ заключается в использовании параметра initializationscript в Start-Job. Если вы определите все свои функции в блоке и передадите блок, они станут доступными.

Решение было найдено в этом посте:

Как начать задание функции, которую я только что определил?

Вот мой предыдущий пример, теперь работающий:

# 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 * 

Если вы не префикс имени вашей функции с ключевым словом functionPowerShell не знает, как к нему относиться. Поскольку вы написали свой скрипт, это в основном переменная со специальным текстом. Который, как показывает ваш вывод, выполняет только те команды, которые он распознает в содержимом этой переменной: Write-Host "OUT:",

Использование правильного синтаксиса скажет PowerShell, что это функция, и у вас есть переменные для передачи в нее, которые вам нужно выполнить:


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

Затем, когда вы вызываете его в своем скрипте, вы просто используете Logx

Получил это далеко. Придется выбежать, попробую позже. 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 * 
Другие вопросы по тегам