¿Pueden los comandos de ejecución Powershell en paralelo?

Tengo un script de PowerShell para hacer un procesamiento por lotes en un grupo de imágenes y me gustaría hacer un parallel processing. Powershell parece tener algunas opciones de procesamiento en segundo plano como start-job, wait-job, etc., pero el único buen recurso que encontré para hacer trabajo en paralelo fue escribir el texto de un script y ejecutarlo ( PowerShell Multithreading )

Idealmente, me gustaría algo parecido al foreach paralelo en .net 4.

Algo bastante parecido a esto:

foreach-parallel -threads 4 ($file in (Get-ChildItem $dir)) { .. Do Work } 

Tal vez sería mejor bajar a c # …

Puede ejecutar trabajos paralelos en Powershell 2 utilizando trabajos en segundo plano . Consulte Start-Job y los otros cmdlets de trabajo.

 # Loop through the server list Get-Content "ServerList.txt" | %{ # Define what each job does $ScriptBlock = { param($pipelinePassIn) Test-Path "\\$pipelinePassIn\c`$\Something" Start-Sleep 60 } # Execute the jobs in parallel Start-Job $ScriptBlock -ArgumentList $_ } Get-Job # Wait for it all to complete While (Get-Job -State "Running") { Start-Sleep 10 } # Getting the information back from the jobs Get-Job | Receive-Job 

La respuesta de Steve Townsend es correcta en teoría, pero no en la práctica, como señaló @likwid. Mi código revisado tiene en cuenta la barrera del contexto de trabajo: ¡ nada cruza esa barrera de forma predeterminada! La variable $_ automática se puede utilizar así en el ciclo, pero no se puede usar directamente dentro del bloque de script porque está dentro de un contexto separado creado por el trabajo.

Para pasar variables del contexto principal al contexto hijo, use el parámetro -ArgumentList en Start-Job para enviarlo y use param dentro del bloque de scripts para recibirlo.

 cls # Send in two root directory names, one that exists and one that does not. # Should then get a "True" and a "False" result out the end. "temp", "foo" | %{ $ScriptBlock = { # accept the loop variable across the job-context barrier param($name) # Show the loop variable has made it through! Write-Host "[processing '$name' inside the job]" # Execute a command Test-Path "\$name" # Just wait for a bit... Start-Sleep 5 } # Show the loop variable here is correct Write-Host "processing $_..." # pass the loop variable across the job-context barrier Start-Job $ScriptBlock -ArgumentList $_ } # Wait for all to complete While (Get-Job -State "Running") { Start-Sleep 2 } # Display output from all jobs Get-Job | Receive-Job # Cleanup Remove-Job * 

(En general, me gusta proporcionar una referencia a la documentación de PowerShell como evidencia de apoyo, pero, por desgracia, mi búsqueda ha sido infructuosa. Si usted sabe dónde está documentada la separación del contexto, ¡envíe un comentario aquí para informarme!)

http://gallery.technet.microsoft.com/scriptcenter/Invoke-Async-Allows-you-to-83b0c9f0

Creé un invoke-async que le permite ejecutar múltiples bloques de script / cmdlets / funciones al mismo tiempo. esto es ideal para trabajos pequeños (exploración de subred o wmi contra 100 de máquinas) porque la sobrecarga para crear un espacio de ejecución frente al tiempo de inicio de la tarea inicial es bastante drástico. Se puede usar así.

con scriptblock,

 $sb = [scriptblock] {param($system) gwmi win32_operatingsystem -ComputerName $system | select csname,caption} $servers = Get-Content servers.txt $rtn = Invoke-Async -Set $server -SetParam system -ScriptBlock $sb 

solo cmdlet / función

 $servers = Get-Content servers.txt $rtn = Invoke-Async -Set $servers -SetParam computername -Params @{count=1} -Cmdlet Test-Connection -ThreadCount 50 

Los trabajos de fondos son costosos de configurar y no son reutilizables. La MVP de PowerShell Oisin Grehan tiene un buen ejemplo de multithreading de PowerShell http://www.nivot.org/2009/01/22/CTP3TheRunspaceFactoryAndPowerShellAccelerators.aspx

(25/10/2010 el sitio está caído):

Utilicé una secuencia de comandos Oisin adaptada para su uso en una rutina de carga de datos aquí:

http://rsdd.codeplex.com/SourceControl/changeset/view/a6cd657ea2be#Invoke-RSDDThreaded.ps1