如何通过引用将变量传递给 Powershell 作业或运行空间



我有Powershell工作。

$cmd = {
  param($a, $b)
  $a++
  $b++
}
$a = 1
$b = 2
Start-Job -ScriptBlock $cmd -ArgumentList $a, $b

如何通过引用传递$a$b,以便在工作完成后更新它们?或者,如何通过引用将变量传递给运行空间?

我刚刚写的简单示例(不介意混乱的代码)

# Test scriptblock
$Scriptblock = {
param([ref]$a,[ref]$b)
$a.Value = $a.Value + 1
$b.Value = $b.Value + 1
}
$testValue1 = 20 # set initial value
$testValue2 = 30 # set initial value
# Create the runspace
$Runspace = [runspacefactory]::CreateRunspace()
$Runspace.ApartmentState = [System.Threading.ApartmentState]::STA
$Runspace.Open()
# create the PS session and assign the runspace
$PS = [powershell]::Create()
$PS.Runspace = $Runspace
# add the scriptblock and add the argument as reference variables
$PS.AddScript($Scriptblock)
$PS.AddArgument([ref]$testValue1)
$PS.AddArgument([ref]$testValue2)
# Invoke the scriptblock
$PS.BeginInvoke()

运行此命令后,将更新 for 测试值,因为它们是通过 ref 传递的。

在PowerShell中,通过引用传递参数总是很尴尬,并且无论如何都不适用于PowerShell作业,正如@bluuf指出的那样。

我可能会做这样的事情:

$cmd = {
    Param($x, $y)
    $x+1
    $y+1
}
$a = 1
$b = 2
$a, $b = Start-Job -ScriptBlock $cmd -ArgumentList $a, $b |
         Wait-Job |
         Receive-Job

上面的代码将变量$a$b传递给脚本块,并在收到作业输出后将修改后的值赋回变量。

一个

更全面的脚本,带有示例。

  • 它还应该包括传递$host或其他东西的能力,从传递的脚本进行write-host,输出到控制台。 但是我没有时间弄清楚如何做到这一点.
$v = 1
function newThread ([scriptblock]$script, [Parameter(ValueFromPipeline)]$param, [Parameter(ValueFromRemainingArguments)]$args) {
    process {
        $Powershell = [powershell]::Create()
        $Runspace = [runspacefactory]::CreateRunspace()
        
        # allows to limit commands available there
        # $InitialSessionState = InitialSessionState::Create()
        # $Runspace.InitialSessionState = $InitialSessionState
        
        $Powershell.Runspace = $Runspace
        $null = $Powershell.AddScript($script)
        $null = $Powershell.AddArgument($param)
        foreach ($v_f in $args) {
            $null = $Powershell.AddArgument($v_f)
        }
        $Runspace.Open()
        $Job = $Powershell.BeginInvoke()
        
        [PSCustomObject]@{
            Job=$Job
            Powershell=$Powershell
        }
    }
}
$script = {
    param([ref]$v,$v2)
    $v.Value++
    $v2
}
$thread = newThread $script ([ref]$v) 3
do {} until ($thread.Job.IsCompleted)
$v1 = $thread.Powershell.EndInvoke($thread.Job)
$thread.Powershell.Dispose()
write-host "end $($v,$v1[0])"

相关内容

  • 没有找到相关文章

最新更新