英文:
Powershell dynamic Start-Job command to execute all powershell scripts in subfolders in parallel
问题
For an important data migration, I would like to execute in parallel multiple scripts inside subfolders:
我想要在子文件夹中并行执行多个脚本进行重要的数据迁移:
I did not succeed to do this:
但我没有成功实现这个:
$folders = Get-ChildItem -Directory
foreach($folder in $folders){
$cmd = "powershell '$folder\script.ps1'"
$job = start-job -ScriptBlock {Invoke-Expression $cmd}
}
谢谢您的帮助!
英文:
For an important data migration, I would like to execute in parallel multiple scripts in side subfolders :
I did not succeed to do this :
$folders = Get-ChildItem -Directory
foreach($folder in $folders){
$cmd = "powershell '$folder\script.ps1'"
$job = start-job -ScriptBlock {Invoke-Expression $cmd}
}
Thank you for your help!
答案1
得分: 2
Multithreaded in PowerShell 7:
Get-ChildItem -Directory | foreach-object -parallel {
& $_\script.ps1
}
英文:
Multithreaded in powershell 7:
Get-ChildItem -Directory | foreach-object -parallel {
& $_\script.ps1
}
答案2
得分: 1
以下是您要翻译的内容:
js2010的答案 是_PowerShell (Core) 7+ 的最简单和最佳解决方案,其中ForEach-Object
现在具有用于并行运行脚本块 的-Parallel
参数。
Windows PowerShell 的解决方案 - 最新且最后一个版本为v5.1的传统PowerShell版本:
Get-ChildItem -Directory |
ForEach-Object {
Start-Job { Set-Location -LiteralPath ($using:_).FullName; .\script.ps1 }
} |
Receive-Job -Wait -AutoRemoveJob
注意:
-
如果不需要在其自己的目录中运行脚本,则以下
Start-Job
调用将起作用:Start-Job { & (Join-Path ($using:_).FullName script.ps1) }
-
如果按需安装模块是一个选项,请考虑安装
ThreadJob
模块,其Start-ThreadJob
提供了一种基于线程的,因此更快速和更轻量级的替代方案,用于Start-Job
创建的慢且资源密集的子进程后台作业。-
一旦安装,您可以在上述代码中简单地用
Start-ThreadJob
替换Start-Job
,因为Start-ThreadJob
与所有与作业相关的cmdlet兼容,例如Receive-Job
。 -
请注意,PowerShell (Core) 7+ 附带
Start-ThreadJob
,尽管通常基于相同的基于线程的基础结构,ForEach-Object -Parallel
选项通常是更简单的选择。
-
英文:
<!-- language-all: sh -->
js2010's answer is the simplest and best solution for PowerShell (Core) 7+, where ForEach-Object
now has a -Parallel
parameter for running script blocks in parallel threads.
A solution for Windows PowerShell - the legacy PowerShell edition whose latest and last version is v5.1:
Get-ChildItem -Directory |
ForEach-Object {
Start-Job { Set-Location -LiteralPath ($using:_).FullName; .\script.ps1 }
} |
Receive-Job -Wait -AutoRemoveJob
Note:
-
If the script needn't be run with its own directory as the working dir., the following
Start-Job
call will do:Start-Job { & (Join-Path ($using:_).FullName script.ps1) }
-
If installing a module on demand is an option, consider installing the
ThreadJob
module, whoseStart-ThreadJob
offers a thread-based and therefore faster and more lightweight alternative to the slow and resource-intensive child-process-based background jobs thatStart-Job
creates.-
Once installed, you can simply substitute
Start-ThreadJob
forStart-Job
in the code above, given thatStart-ThreadJob
is compatible with all job-related cmdlets, such asReceive-Job
. -
Note that PowerShell (Core) 7+ comes with
Start-ThreadJob
, though theForEach-Object -Parallel
option - built on the same thread-based infrastructure - is often the simpler choice.
-
答案3
得分: 0
<strike>您可以使用Invoke-Command
来进行并发处理。</strike>以下是一个可能满足您要求的示例。
Get-ChildItem -Directory | ForEach-Object {
$folderPath = $_.FullName
Start-Job -ScriptBlock { .\script.ps1 $using:folderPath }
}
Get-Job | ForEach-Object {
$result = Wait-Job $_ | Receive-Job
Remove-Job $_
$result
}
英文:
<strike>You can use Invoke-Command
for concurrent processing.</strike> Here's an example that may meet your requirements.
Get-ChildItem -Directory | ForEach-Object {
$folderPath = $_.FullName
Start-Job -ScriptBlock { .\script.ps1 $using:folderPath }
}
Get-Job | ForEach-Object {
$result = Wait-Job $_ | Receive-Job
Remove-Job $_
$result
}
答案4
得分: 0
我找到了一个可行的解决方案,通过使用Start-Process,它满足了我的需求。谢谢大家。
英文:
I found a working solution, by using Start-Process, it answer my need. THank you every one
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论