2012-01-05 6 views
11

Ho il seguente codice.Powershell start-job -scriptblock non può riconoscere la funzione definita nello stesso file?

function createZip 
{ 
Param ([String]$source, [String]$zipfile) 
Process { echo "zip: $source`n  --> $zipfile" } 
} 

try { 
    Start-Job -ScriptBlock { createZip "abd" "acd" } 
} 
catch { 
    $_ | fl * -force 
} 
Get-Job | Wait-Job 
Get-Job | receive-job 
Get-Job | Remove-Job 

Tuttavia, lo script restituisce il seguente errore.

Id    Name   State  HasMoreData  Location    Command     
--    ----   -----  -----------  --------    -------     
309    Job309   Running True   localhost   createZip "a... 
309    Job309   Failed  False   localhost   createZip "a... 
Receive-Job : The term 'createZip' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again. 
At line:17 char:22 
+ Get-Job | receive-job <<<< 
    + CategoryInfo   : ObjectNotFound: (function:createZip:String) [Receive-Job], CommandNotFoundException 
    + FullyQualifiedErrorId : CommandNotFoundException 

Sembra il nome della funzione non può essere riconosciuto all'interno del blocco di script di start-job. Ho provato anche function:createZip.

risposta

13

Start-Job in realtà gira un'altra istanza di PowerShell.exe che non ha la funzione createZip. È necessario includere tutto in un blocco di script:

$createZip = { 
    param ([String]$source, [String]$zipfile) 
    Process { echo "zip: $source`n  --> $zipfile" } 
} 

Start-Job -ScriptBlock $createZip -ArgumentList "abd", "acd" 

Un esempio restituire un messaggio di errore dal processo in background:

$createZip = { 
    param ([String] $source, [String] $zipfile) 

    $output = & zip.exe $source $zipfile 2>&1 
    if ($LASTEXITCODE -ne 0) { 
     throw $output 
    } 
} 

$job = Start-Job -ScriptBlock $createZip -ArgumentList "abd", "acd" 
$job | Wait-Job | Receive-Job 

Si noti inoltre che utilizzando un throw l'oggetto processo State sarà " Non riuscito "in modo da poter ottenere solo i lavori che non sono riusciti: Get-Job -State Failed.

+0

Grazie. Sembra che l'eccezione sollevata in un'altra istanza di PowerShell non possa essere catturata. Qual è il modo migliore per catturare l'eccezione? – ca9163d9

+0

@NickW Sicuro. Controlla la mia risposta aggiornata. –

+1

Grazie per questo - ho avuto una domanda simile e ora sono d'oro! – marceljg

5

Se siete ancora nuovo per utilizzare Start-Job e ricevere-lavoro, e si vuole eseguire il debug la funzione più facilmente, provate questo modulo:

$createZip = { 
    function createzipFunc { 
    param ([String]$source, [String]$zipfile) 
    Process { echo "zip: $source`n  --> $zipfile" } 
    } 
    #other funcs and constants here if wanted... 
    } 
    # some secret sauce, this defines the function(s) for us as locals 
    invoke-expression $createzip 

    #now test it out without any job plumbing to confuse you 
    createzipFunc "abd" "acd" 

    # once debugged, unfortunately this makes calling the function from the job 
    # slightly harder, but here goes... 
    Start-Job -initializationScript $createZip -scriptblock {param($a,$b) ` 
createzipFunc $a $b } -ArgumentList "abc","def" 

Non tutto reso più semplice dal fatto non mi definisco la mia funzione di filtro semplice, ma che ho fatto perché volevo passare un numero di funzioni nel mio lavoro alla fine.

Ci scusiamo per aver estratto questo thread, ma ha risolto il mio problema anche in modo così elegante. E così ho dovuto aggiungere questo pezzetto di salsa che avevo scritto durante il debug del mio lavoro con PowerShell.

+2

Mi piace questo approccio. Una cosa da aggiungere è talvolta Invoke-Expression' si ripeterà 'Invoke-Expression: Impossibile valutare il parametro 'Command' perché il suo argomento viene specificato come blocco di script e non vi è alcun input. Un blocco di script non può essere valutato senza input. Ho scoperto che se si passa la variabile come una stringa 'invoke-expression" $ createzip "' risolve il problema. – Adarsha