2012-10-07 42 views
15

No estoy seguro de si esto se debe a una necesidad de multi-threading, basado en trabajo o asincrónico, pero básicamente tengo una función de script de Powershell que toma varios parámetros y necesita llamarlo varias veces con diferentes parámetros y hacer que se ejecuten en paralelo.Cómo ejecutar una función de Powershell varias veces en paralelo

la actualidad, que llame a la función como esta:

Execute "param1" "param2" "param3" "param4" 

¿Cómo puedo llamar a esto varias veces sin esperar a que cada llamada a ejecutar retorno a la persona que llama?

Actualmente estoy ejecutando v2.0 pero puedo actualizar si es necesario

EDIT: esto es lo que tengo hasta ahora, que no funciona:

$cmd = { 
    param($vmxFilePath,$machineName,$username,$password,$scriptTpath,$scriptFile,$uacDismissScript,$snapshotName) 
    Execute $vmxFilePath $machineName $username $password $scriptTpath $scriptFile $uacDismissScript $snapshotName 
} 

Start-Job -ScriptBlock $cmd -ArgumentList $vmxFilePath, $machineName, $username $password, $scriptTpath, $scriptFile, $uacDismissScript, $snapshotName 

consigo un error:

cannot convert 'system.object[]' to the type 'system.management.automation.scriptblock' required by parameter 'initializationscript'. specified method is not supported 

EDIT2: He modificado mi script, pero sigo teniendo el error mencionado anteriormente. Aquí está mi mod:

$cmd = { 
    param($vmxFilePath,$machineName,$username,$password,$scriptTpath,$scriptFile,$uacDismissScript,$snapshotName) 
    Execute $vmxFilePath $machineName $username $password $scriptTpath $scriptFile $uacDismissScript $snapshotName 
} 

Start-Job -ScriptBlock $cmd -ArgumentList $vmxFilePath, $machineName, $username $password, $scriptTpath, $scriptFile, $uacDismissScript, $snapshotName 

Respuesta

29

No se necesita actualizar para esto. Defina un bloque de script y use Start-Job para ejecutar el bloque de scripts tantas veces como sea necesario. Ejemplo:

$cmd = { 
    param($a, $b) 
    Write-Host $a $b 
} 

$foo = "foo" 

1..5 | ForEach-Object { 
    Start-Job -ScriptBlock $cmd -ArgumentList $_, $foo 
} 

El bloque de script toma 2 parámetros $a y $b que se pasan por la opción -ArgumentList. En el ejemplo anterior, las asignaciones son $_$a y $foo$b. $foo es solo un ejemplo para un parámetro configurable pero estático.

Ejecute Get-Job | Remove-Job en algún punto para eliminar los trabajos finalizados de la cola (o Get-Job | % { Receive-Job $_.Id; Remove-Job $_.Id } si desea recuperar la salida).

+0

Todavía estoy teniendo dificultades para mapear su solución para conseguir mi propio guión para trabajar. Comenzaré de forma simple, y solo intentaré que Start-Job ejecute mi scriptblock con los argumentos que requiere mi función personalizada, Execute. Tal vez puedes expandirte? ¿Es $ foo un parámetro además de los especificados por param ($ a, $ b)? – JohnZaj

+0

Ahora veo, gracias. Aun así recibo el error. Si no está seguro de lo que podría ser, crearé una publicación/pregunta por separado. – JohnZaj

+0

Para fines de prueba, reemplace la llamada de su función 'Execute()' con un código que solo haga eco de los parámetros. ¿Eso funciona? Si lo hace, el problema radica en la función a la que desea llamar. –

16

Aquí hay una ScriptBlock falso rápida para el propósito de la prueba:

$Code = { 
    param ($init) 
    $start = Get-Date 
    (1..30) | % { Start-Sleep -Seconds 1; $init +=1 } 
    $stop = Get-Date 
    Write-Output "Counted from $($init - 30) until $init in $($stop - $start)." 
} 

Este ScriptBlock puede entonces ser transmitida a Start-Job, con por ejemplo 3 parámetros (10, 15, 35)

$jobs = @() 
(10,15,35) | % { $jobs += Start-Job -ArgumentList $_ -ScriptBlock $Code } 

Wait-Job -Job $jobs | Out-Null 
Receive-Job -Job $jobs 

Esto crea 3 trabajos, asígnelos a la variable $jobs, los ejecuta en paralelo y luego espera a que estos 3 trabajos finalicen y recupera los resultados:

Counted from 10 until 40 in 00:00:30.0147167. 
Counted from 15 until 45 in 00:00:30.0057163. 
Counted from 35 until 65 in 00:00:30.0067163. 

Esto no sucedió 90 segundos para ejecutar, solamente 30.

Una de las partes difíciles es proporcionar -Argumentlist a Start-Job, e incluyen un bloque param() dentro de la ScriptBlock. De lo contrario, sus valores nunca serán vistos por el scriptblock.

3

Lamento que todos hayan perdido su problema, sé que ya es demasiado tarde, pero ...

Este error se debe a que le falta una coma entre $ nombre de usuario y $ contraseña en su lista.

Puede probarlo con este fragmento, que Modelé fuera de las respuestas anteriores:

$cmd = { 
    param($a, $b, $c, $d) 
} 
$foo = "foo" 
$bar = "bar" 
start-job -scriptblock $cmd -ArgumentList "a", $foo, $bar, "gold" #added missing comma for this to work 
2

Se puede utilizar una alternativa que puede ser más rápido que los puestos de trabajo que invocan si la función no es mucho ejecutando uno . El hilo máximo es 25 y solo invoco esta función 10 veces, por lo que espero que mi tiempo de ejecución total sea de 5 segundos. Puede ajustar Measure-Command alrededor de la instrucción 'results =' para ver las estadísticas.

Ejemplo:

$ScriptBlock = { 
     Param ([int]$RunNumber) 

     Start-Sleep -Seconds 5 
     Return $RunNumber 

    } 



    $runNumbers = @(1..10) 


    $MaxThreads = 25 
    $runspacePool = [RunspaceFactory ]::CreateRunspacePool(1, $MaxThreads) 
    $runspacePool.Open() 


    $pipeLines = foreach($num in $runNumbers){ 

           $pipeline = [powershell]::Create() 
           $pipeline.RunspacePool = $runspacePool 
           $pipeline.AddScript($ScriptBlock) | Out-Null 
           $pipeline.AddArgument($num) | Out-Null 

           $pipeline | Add-Member -MemberType NoteProperty -Name 'AsyncResult' -Value $pipeline.BeginInvoke() -PassThru 
        } 



    #obtain results as they come. 
    $results = foreach($pipeline in $pipeLines){ 
         $pipeline.EndInvoke($pipeline.AsyncResult) 
       } 


    #cleanup code. 
    $pipeLines | % { $_.Dispose()} 
    $pipeLines = $null 
    if ($runspacePool) { $runspacePool.Close()} 

    #your results 
    $results 
Cuestiones relacionadas