2014-12-08 2 views
10

Copia e incolla il seguente in un nuovo script PowerShell ISE e colpire F5:comprensione gamma di funzioni nel flusso di lavoro PowerShell

workflow workflow1{ 
    "in workflow1" 
    func1 
} 
function func1 { 
    "in func1" 
    func2 
} 
function func2 { 
    "in func2" 
} 
workflow1 

l'errore che ottengo è:

Il termine 'func2' è non riconosciuto come nome di un cmdlet, funzione, file di script o programma eseguibile

Non lo capisco. Perché func1 dovrebbe essere nello scope ma non func2? Qualsiasi aiuto molto apprezzato. TIA.

+0

Questo è interessante. Se dovessi indovinare sarebbe perché 'Func1' è invocato direttamente dalla definizione del flusso di lavoro ma' func2' non lo è. Dalla lettura dell'elaborazione del flusso di lavoro sembrano esserci alcune restrizioni sul lavoro tra gli ambiti. – JNK

risposta

9

Pensa ai flussi di lavoro come elementi di programmazione miopi.

Un flusso di lavoro non può vedere oltre ciò che è immediatamente disponibile nell'ambito. Le funzioni nidificate non funzionano con un singolo flusso di lavoro, perché non possono vederle.

La correzione consiste nel nidificare i flussi di lavoro insieme alle funzioni nidificate. Come ad esempio questo:

workflow workflow1 
{ 
    function func1 
    { 
     "in func1" 
     workflow workflow2 
     { 
      function func2 
      { 
       "in func2" 
      } 
      func2 
     } 
     "in workflow2" 
     workflow2 
    } 
    "in workflow1" 
    func1 
} 
workflow1 

Poi si vede le funzioni nidificate:

in workflow1 
in func1 
in workflow2 
in func2 

più su di esso here

+2

Grazie Micky. Un po 'fastidioso, ho delle funzioni che voglio usare in diversi flussi di lavoro, ma ora non posso. Kinda sconfigge lo scopo delle funzioni IMO. – jamiet

1

Non proprio una risposta alla tua domanda, ma più una traccia da seguire. Metterlo in un commento sarebbe troppo lungo.

Da here:

Quando si esegue un flusso di lavoro di script, Windows PowerShell analizza lo script in un albero di sintassi astratta (AST). La presenza della parola chiave "workflow" fa sì che il compilatore script-flusso di lavoro utilizzi questo AST su genera XAML, il formato richiesto dal runtime di Windows Workflow Foundation . Per creare l'esperienza utente per interagire con questo flusso di lavoro , creiamo quindi una funzione wrapper con gli stessi parametri , ma coordina invece l'esecuzione del flusso di lavoro all'interno di l'esecutivo del flusso di lavoro PowerShell. È possibile vedere sia la funzione wrapper e il codice XAML generato eseguendo:

Get-Command workflow1 |Format-List * 

L'ho fatto per il flusso di lavoro specifico (vedere il Workflow1 nel comando sopra) e sia XAML e PowerShell generato il codice sono .. . interessante. Il codice XAML non include alcun riferimento a func2, ma contiene un riferimento a func1.

+0

interessante, sembra di essere su qualcosa di David. Continuerò a scavare – jamiet

+1

Se chiami la funzione 'Get-ChildItem: func *' all'interno del flusso di lavoro, non elenca affatto 'func1' o' func2'. Sembrano esserci molte [restrizioni apparentemente arbitrarie sui flussi di lavoro] (http://blogs.technet.com/b/heyscriptingguy/archive/2013/01/02/powershell-workflows-restrictions.aspx), ma non sembra essere molto ben documentato Voglio dire, ci sono [un sacco di esempi] (http://technet.microsoft.com/en-us/library/jj574157.aspx), ma questo non spiega come funzionano le cose, solo che lo fanno. [Questo] (http://blogs.technet.com/b/heyscriptingguy/archive/tags/workflow/) è la migliore risorsa che riesca a trovare. –

0

Per riassumere vagamente tutte le risposte, non mettono in discussione il motivo per cui si comporta in questo modo, accetta solo quello che fa e gestiscilo. Giusto.

Ho scritto un'intera pipeline di distribuzione in Powershell senza flusso di lavoro e mi piacerebbe ottimizzarlo utilizzando "foreach -parallel" del flusso di lavoro, tuttavia sembra che la tassa sul farlo sia che dovrei tornare indietro e riscrivi l'intera cosa nel flusso di lavoro. Questa è una tassa troppo grande da pagare, purtroppo, solo per ottenere un ciclo foreach parallelo.

Lezione appresa: utilizzare il flusso di lavoro PowerShell sin dall'inizio.

0

È possibile racchiudere le funzioni e le relative chiamate all'interno di InlineScript, che potrebbe essere uno script per sistema. Quindi esegui questo inlinescript all'interno di un ciclo foreach -Parallel che funziona attraverso i sistemi che vuoi interrogare.