如何使用Powershell中的BeginInvoke从内部向控制台写入启动作业?
我是Powershell的新手,我正在尝试编写一个脚本来运行一些并行作业。我希望这些作业在运行完成后能够输出一些数据,但我似乎无法正确执行。我把它弄得有点乱,听起来写输出是一种方式,但当我查看作业返回的对象时,输出数组中没有任何内容。这就是我到目前为止所做的:如何使用Powershell中的BeginInvoke从内部向控制台写入启动作业?,powershell,Powershell,我是Powershell的新手,我正在尝试编写一个脚本来运行一些并行作业。我希望这些作业在运行完成后能够输出一些数据,但我似乎无法正确执行。我把它弄得有点乱,听起来写输出是一种方式,但当我查看作业返回的对象时,输出数组中没有任何内容。这就是我到目前为止所做的: $connection = @{ connection = (Connect-Site -Url "site.com" -Browser) } $importScript = { param($p1)
$connection = @{ connection = (Connect-Site -Url "site.com" -Browser) }
$importScript = {
param($p1)
#get the list name from the file name
$name = $_.Name.LastIndexOf(".")
$path = $_.FullName
$listName = $_.Name.Substring(0, $name)
$dstSite = Connect-Site -Url "site.com" -UseCredentialsFrom $p1.connection
Write-Output "$name, $path, $listName"
Write-Output $dstSite
}
Write-Host "Migration started at $(Get-Date)"
Get-ChildItem -Path "C:\ProjExports" |
Foreach-Object {
$running = @(Get-Job | Where-Object { $_.State -eq 'Running' })
if ($running.Count -le 10) {
Start-Job {
# create and start the job
$p = [PowerShell]::Create()
$null = $p.AddScript($importScript).AddArgument($connection)
$job = $p.BeginInvoke()
$done = $job.AsyncWaitHandle.WaitOne()
$out = $p.EndInvoke($job)
}
} else {
$running | Wait-Job
}
Get-Job | Receive-Job
}
我的印象是,$out应该包含AddScript中脚本的Write输出中的项目,但它似乎总是空的。您将运行空间和作业结合在一起,这是不必要的。工作可以像这样简单。作业会创建一个新流程,因此会有一定的延迟
'hi','you','me' | foreach-object {
start-job { param ($a) write-output "$a there" } -args $_
} | receive-job -wait -autoremovejob
you there
me there
hi there
如果您有powershell 7,则可以改用start threadjob或foreach object-parallel。或下载powershell 5中的模块
下面是一个真实的threadjob示例:
echo microsoft.com yahoo.com | foreach {
start-threadjob {
param ($hostname)
test-connection -count 1 $hostname } -argumentlist $_
} | receive-job -wait -autoremovejob
您将运行空间和作业结合起来,这是不必要的。工作可以像这样简单。作业会创建一个新流程,因此会有一定的延迟
'hi','you','me' | foreach-object {
start-job { param ($a) write-output "$a there" } -args $_
} | receive-job -wait -autoremovejob
you there
me there
hi there
如果您有powershell 7,则可以改用start threadjob或foreach object-parallel。或下载powershell 5中的模块
下面是一个真实的threadjob示例:
echo microsoft.com yahoo.com | foreach {
start-threadjob {
param ($hostname)
test-connection -count 1 $hostname } -argumentlist $_
} | receive-job -wait -autoremovejob
我已编辑代码以反映缺少的第一行。我之所以这样做,是因为我试图将一个对象传递到每个异步作业中。使用start-job-args似乎不会传入完整对象,但反序列化版本不起作用,与-parallel.start-threadjob和foreach-object-parallel使用完整对象相同。我已编辑代码以反映缺少的第一行。我之所以这样做,是因为我试图将一个对象传递到每个异步作业中。使用start-job-args似乎不会传入完整的对象,但会传入一个反序列化版本,该版本不起作用,对于每个-parallel.start-threadjob和foreach-object-parallel使用完整对象。