$RunspaceCollection = @()
$RunspacePool = [RunspaceFactory]::CreateRunspacePool(1,5)
$RunspacePool.Open()
$code = @({'somecode'},{'someothercode'})
Foreach ($test in $case) {
$finalcode= {
Invoke-Command -ScriptBlock [scriptblock]::create($code[$test])
}.GetNewClosure()
$Powershell = [PowerShell]::Create().AddScript($finalcode)
$Powershell.RunspacePool = $RunspacePool
[Collections.Arraylist]$RunspaceCollection += New-Object -TypeName PSObject -Property @{
Runspace = $PowerShell.BeginInvoke()
PowerShell = $PowerShell
}}
当
finalcode
发生时,GetNewClosure()
变量不会扩展,因此$code[$test]
进入了运行空间而不是实际代码,并且无法获得所需的结果。有什么建议吗?使用答案中的方法,我在运行空间中得到了它,但是它不能正确执行。我可以确认我的命令已加载到运行空间中(至少在运行空间内的调试器中,我可以执行该指令而无需点源)
[System.Management.Automation.PSSerializer]::Deserialize('<ObjsVersion="1.1.0.1" xmlns="http://schemas.microsoft.com/powershell/2004/04">
<SBK> My-Command -Par1 "egweg" -Par2 "qwrqwr" -Par3 "wegweg"</SBK>
</Objs>')
这是我在运行空间的调试器中看到的
Stopped at: $a = Invoke-Command -ScriptBlock { $([System.Management.Automation.PSSerializer]::Deserialize('<Objs Version="1.1.0.1" xmlns="http://schemas.microsoft.com/powershell/2004/04">
[DBG]: [Process:8064]: [Runspace12]: PS C:\git\infrastructure_samples>>
Stopped at: $a = Invoke-Command -ScriptBlock { $([System.Management.Automation.PSSerializer]::Deserialize('<Objs Version="1.1.0.1" xmlns="http://schemas.microsoft.com/powershell/2004/04">
[DBG]: [Process:8064]: [Runspace12]: PS C:\git\infrastructure_samples>> s
Stopped at: </Objs>')) }
最佳答案
您的代码的问题在于AddScript
类的PowerShell
方法需要一个字符串,而不是ScriptBlock
。当您将ScriptBlock
转换为字符串时,任何关闭都将丢失。为了解决这个问题,您可以使用AddArgument
方法将参数传递给脚本:
$RunspaceCollection = New-Object System.Collections.Generic.List[Object]
$RunspacePool = [RunspaceFactory]::CreateRunspacePool(1,5)
$RunspacePool.Open()
$code = @({'somecode'},{'someothercode'})
$finalcode= {
param($Argument)
Invoke-Command -ScriptBlock ([scriptblock]::create($Argument))
}
Foreach ($test in $case) {
$Powershell = [PowerShell]::Create().AddScript($finalcode).AddArgument($code[$test])
$Powershell.RunspacePool = $RunspacePool
$RunspaceCollection.Add((New-Object -TypeName PSObject -Property @{
Runspace = $PowerShell.BeginInvoke()
PowerShell = $PowerShell
}))
}