【问题标题】:PowerShell process handling - Start multiple SqlPackage.exe processes in a PowerShell loopPowerShell 进程处理 - 在 PowerShell 循环中启动多个 SqlPackage.exe 进程
【发布时间】:2017-07-12 09:18:23
【问题描述】:

有没有办法启动 SqlPackage.exe 的工作进程,其中目标数据库存储在一个数组中,以便您可以循环访问它(所有其他参数都相同)?

我想禁止来自这些进程的所有打印,除非出现错误,然后在最后显示报告。我该怎么做?

现在我有一个类似以下的循环(作为开始):

$arguments = @(
    "/Action:Import",
    "/SourceFile:$($bacpacSource)",
    "/TargetServerName:$($serverName)"
)

for ($i = 1; $i -lt 4; $i++) {
    $targetDatabase = $baseDatabaseName + $i
    $arguments += "/TargetDatabaseName:$($targetDatabase)"
    Start-Process -FilePath $sqlPackagePath $arguments -NoNewWindow -PassThru
}

我在某处找到了Start-Process,我确信我需要存储此函数返回的对象并以某种方式使用它。我想启动所有进程,然后等待所有进程完成,此时我将调查是否全部成功。如果出现故障,我想从该过程中打印错误信息。现在所有进程同时打印,并且在它们全部完成后整个缓冲区都损坏了。

这在 PowerShell 中可行吗?

PS:该脚本旨在稍后将使用 .dacpac 文件的更新部署到生产中,但这个问题与 Windows 进程和错误的处理密切相关。

编辑:我可能需要一种方法来一次创建和维护最大数量的进程,并在完成某些进程时进行交换。因此,假设任何时候我可能只有 10 个 SqlPackage.exe 进程连接到服务器。我将如何在 PowerShell 中创建这样的barrier lock(认为这就是它的名称)?

【问题讨论】:

标签: windows multithreading powershell


【解决方案1】:

我认为您可以按如下方式合并 PowerShell 作业,将每个任务推送到后台作业中,然后使用 Wait-Job 等待它们完成,然后再通过 Receive-Job 返回它们的输出:

$arguments = @(
    "/Action:Import",
    "/SourceFile:$($bacpacSource)",
    "/TargetServerName:$($serverName)"
)

for ($i = 1; $i -lt 4; $i++) {
    $targetDatabase = $baseDatabaseName + $i
    $arguments += "/TargetDatabaseName:$($targetDatabase)"
    Start-Job -ScriptBlock { Start-Process -FilePath $sqlPackagePath $arguments -NoNewWindow -PassThru }
}

Get-Job | Wait-Job | Receive-Job

【讨论】:

  • 这就是我在关注您的评论后的样子。我只需要弄清楚如何检查任何给定的作业是否已经崩溃,这样我就可以检查 ExitCode 和 Error。我可以在工作中做到这一点吗?现在你把它包装在一个工作中,而我只是把它切换回我以前的版本& $sqlPackage $arguments(我还在 ScriptBlock 中重新声明了 param($arguments),因为它似乎无法访问外部范围并使用 -ArgumentList (,$arguments)) 传递它们
  • 经过一些实验,我认为我必须采用某种屏障方法,或者一组工人和一组任务(我可以像上面那样生成)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-04-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-22
  • 1970-01-01
相关资源
最近更新 更多