Informazioni sui concetti chiave del flusso di lavoro di PowerShell per i runbook di AutomazioneLearning key Windows PowerShell Workflow concepts for Automation runbooks

I Runbook in Automazione di Azure vengono implementati come flussi di lavoro di Windows PowerShell.Runbooks in Azure Automation are implemented as Windows PowerShell Workflows. Un flusso di lavoro di Windows PowerShell è simile a uno script Windows PowerShell, ma presenta alcune differenze significative che possono generare confusione in un nuovo utente.A Windows PowerShell Workflow is similar to a Windows PowerShell script but has some significant differences that can be confusing to a new user. Anche se lo scopo di questo articolo è illustrare come scrivere runbook con il flusso di lavoro di PowerShell, è consigliabile scrivere runbook con PowerShell, a meno che non siano necessari checkpoint.While this article is intended to help you write runbooks using PowerShell workflow, we recommend you write runbooks using PowerShell unless you need checkpoints. Esistono numerose differenze sintattiche nella creazione dei runbook del flusso di lavoro di PowerShell e queste differenze richiedono maggiore impegno nella scrittura di flussi di lavoro efficaci.There are several syntax differences when authoring PowerShell Workflow runbooks and these differences require a bit more work to write effective workflows.

Un flusso di lavoro è una sequenza di passaggi programmati connessi che eseguono operazioni a esecuzione prolungata o richiedono il coordinamento di più passaggi tra più dispositivi o nodi gestiti.A workflow is a sequence of programmed, connected steps that perform long-running tasks or require the coordination of multiple steps across multiple devices or managed nodes. I vantaggi di un flusso di lavoro rispetto a un normale script includono la possibilità di eseguire simultaneamente un'azione su più dispositivi e di eseguire il ripristino automatico dagli errori.The benefits of a workflow over a normal script include the ability to simultaneously perform an action against multiple devices and the ability to automatically recover from failures. Un flusso di lavoro di Windows PowerShell è uno script di Windows PowerShell che usa Windows Workflow Foundation.A Windows PowerShell Workflow is a Windows PowerShell script that uses Windows Workflow Foundation. Pur essendo scritto con la sintassi di Windows PowerShell e avviato da Windows PowerShell, un flusso di lavoro viene elaborato da Windows Workflow Foundation.While the workflow is written with Windows PowerShell syntax and launched by Windows PowerShell, it is processed by Windows Workflow Foundation.

Per informazioni dettagliate sugli argomenti inclusi in questo articolo, vedere Informazioni sul flusso di lavoro di Windows PowerShell.For complete details on the topics in this article, see Getting Started with Windows PowerShell Workflow.

Struttura di base di un flusso di lavoroBasic structure of a workflow

Il primo passaggio per la conversione di uno script PowerShell in un flusso di lavoro consiste nell'includerlo con la parola chiave Flusso di lavoro .The first step to converting a PowerShell script to a PowerShell workflow is enclosing it with the Workflow keyword. Un flusso di lavoro di Windows PowerShell inizia con la parola chiave Flusso di lavoro seguita dal corpo dello script racchiuso tra parentesi graffe.A workflow starts with the Workflow keyword followed by the body of the script enclosed in braces. Il nome del flusso di lavoro segue la parola chiave Workflow, come illustrato nella sintassi seguente:The name of the workflow follows the Workflow keyword as shown in the following syntax:

Workflow Test-Workflow
{
    <Commands>
}

Il nome del flusso di lavoro deve corrispondere al nome del Runbook di Automazione.The name of the workflow must match the name of the Automation runbook. Se il runbook viene importato, il nome del file deve corrispondere al nome del flusso di lavoro e terminare con l'estensione ps1.If the runbook is being imported, then the filename must match the workflow name and must end in .ps1.

Per aggiungere parametri al flusso di lavoro, utilizzare la parola chiave Param esattamente come si farebbe con uno script.To add parameters to the workflow, use the Param keyword just as you would to a script.

Modifiche al codiceCode changes

Il codice del flusso di lavoro di PowerShell è quasi identico al relativo codice di script, fatta eccezione per alcune modifiche significative.PowerShell workflow code looks almost identical to PowerShell script code except for a few significant changes. Le sezioni seguenti descrivono le modifiche che è necessario apportare a uno script di PowerShell per l'esecuzione in un flusso di lavoro.The following sections describe changes that you need to make to a PowerShell script for it to run in a workflow.

attivitàActivities

Un'attività è un'operazione specifica in un flusso di lavoro.An activity is a specific task in a workflow. Così come uno script è costituito da uno o più comandi, un flusso di lavoro è costituito da una o più attività eseguite in sequenza.Just as a script is composed of one or more commands, a workflow is composed of one or more activities that are carried out in a sequence. Il flusso di lavoro di Windows PowerShell converte automaticamente molti dei cmdlet di Windows PowerShell in attività quando esegue un flusso di lavoro.Windows PowerShell Workflow automatically converts many of the Windows PowerShell cmdlets to activities when it runs a workflow. Quando si specifica uno di questi cmdlet in un runbook, l'attività corrispondente viene eseguita da Windows Workflow Foundation.When you specify one of these cmdlets in your runbook, the corresponding activity is run by Windows Workflow Foundation. I cmdlet senza un'attività corrispondente vengono eseguiti automaticamente dal flusso di lavoro di Windows PowerShell in un'attività InlineScript .For those cmdlets without a corresponding activity, Windows PowerShell Workflow automatically runs the cmdlet within an InlineScript activity. Esiste un set di cmdlet che sono esclusi e non possono essere usati in un flusso di lavoro, a meno che non vengano inclusi in modo esplicito in un blocco InlineScript.There is a set of cmdlets that are excluded and cannot be used in a workflow unless you explicitly include them in an InlineScript block. Per altri dettagli su questi concetti, vedere l'articolo relativo all' uso di attività in flussi di lavoro di script.For further details on these concepts, see Using Activities in Script Workflows.

Le attività dei flussi di lavoro condividono un set di parametri comuni per configurare il proprio funzionamento.Workflow activities share a set of common parameters to configure their operation. Per informazioni dettagliate sui parametri comuni dei flussi di lavoro, vedere about_WorkflowCommonParameters.For details about the workflow common parameters, see about_WorkflowCommonParameters.

Parametri posizionaliPositional parameters

Non è possibile utilizzare i parametri posizionali con attività e cmdlet in un flusso di lavoro.You can't use positional parameters with activities and cmdlets in a workflow. Tutto ciò significa che è necessario utilizzare nomi di parametro.All this means is that you must use parameter names.

Si consideri, ad esempio, il codice seguente per rilevare tutti i servizi in esecuzione.For example, consider the following code that gets all running services.

Get-Service | Where-Object {$_.Status -eq "Running"}

Se si tenta di eseguire lo stesso codice in un flusso di lavoro, viene visualizzato un messaggio simile al seguente: "Impossibile risolvere il set di parametri mediante i parametri denominati specificati".If you try to run this same code in a workflow, you receive a message like "Parameter set cannot be resolved using the specified named parameters." Per risolvere il problema, specificare il nome del parametro come indicato di seguito.To correct this, provide the parameter name as in the following.

Workflow Get-RunningServices
{
    Get-Service | Where-Object -FilterScript {$_.Status -eq "Running"}
}

Oggetti deserializzatiDeserialized objects

Gli oggetti nei flussi di lavoro vengono deserializzati.Objects in workflows are deserialized. Ciò significa che le relative proprietà sono ancora disponibili, ma non i relativi metodi.This means that their properties are still available, but not their methods. Ad esempio, si consideri il codice PowerShell riportato di seguito che consente di arrestare un servizio utilizzando il metodo Stop dell'oggetto Service.For example, consider the following PowerShell code that stops a service using the Stop method of the Service object.

$Service = Get-Service -Name MyService
$Service.Stop()

Se si tenta di eseguire questa operazione in un flusso di lavoro, viene visualizzato un errore indicante che la "chiamata al metodo non è supportata in un flusso di lavoro di Windows PowerShell".If you try to run this in a workflow, you receive an error saying "Method invocation is not supported in a Windows PowerShell Workflow."

È possibile eseguire il wrapping di queste due righe di codice in un blocco InlineScript. In questo caso, $Service sarà un oggetto Service all'interno del blocco.One option is to wrap these two lines of code in an InlineScript block in which case $Service would be a service object within the block.

Workflow Stop-Service
{
    InlineScript {
        $Service = Get-Service -Name MyService
        $Service.Stop()
    }
}

Un'altra opzione consiste nell'utilizzare un altro cmdlet che esegue la stessa funzionalità del metodo, se disponibile.Another option is to use another cmdlet that performs the same functionality as the method, if one is available. Nel presente esempio il cmdlet Stop-Service fornisce la stessa funzionalità del metodo Stop e consente di usare quanto segue per un flusso di lavoro.In our sample, the Stop-Service cmdlet provides the same functionality as the Stop method, and you could use the following for a workflow.

Workflow Stop-MyService
{
    $Service = Get-Service -Name MyService
    Stop-Service -Name $Service.Name
}

InlineScriptInlineScript

L'attività InlineScript risulta utile quando è necessario eseguire uno o più comandi tradizionali come script piuttosto che flusso di lavoro PowerShell.The InlineScript activity is useful when you need to run one or more commands as traditional PowerShell script instead of PowerShell workflow. Mentre i comandi di un flusso di lavoro vengono inviati a Windows Workflow Foundation per l'elaborazione, i comandi in un blocco InlineScript vengono elaborati da Windows PowerShell.While commands in a workflow are sent to Windows Workflow Foundation for processing, commands in an InlineScript block are processed by Windows PowerShell.

InlineScript usa la sintassi indicata di seguito.InlineScript uses the following syntax shown below.

InlineScript
{
    <Script Block>
} <Common Parameters>

È possibile restituire l'output di un InlineScript assegnando l'output a una variabile.You can return output from an InlineScript by assigning the output to a variable. Nell'esempio seguente viene arrestato un servizio e viene quindi restituito il nome del servizio.The following example stops a service and then outputs the service name.

Workflow Stop-MyService
{
    $Output = InlineScript {
        $Service = Get-Service -Name MyService
        $Service.Stop()
        $Service
    }

    $Output.Name
}

È possibile passare i valori in un blocco InlineScript, ma è necessario utilizzare il modificatore di ambito $Using .You can pass values into an InlineScript block, but you must use $Using scope modifier. L'esempio seguente è identico all'esempio precedente, ad eccezione del fatto che il nome del servizio viene fornito da una variabile.The following example is identical to the previous example except that the service name is provided by a variable.

Workflow Stop-MyService
{
    $ServiceName = "MyService"

    $Output = InlineScript {
        $Service = Get-Service -Name $Using:ServiceName
        $Service.Stop()
        $Service
    }

    $Output.Name
}

Anche se possono rivelarsi di importanza critica in alcuni flussi di lavoro, le attività di InlineScript non supportano costrutti di flussi di lavoro e devono essere usate solo se necessario per i motivi seguenti:While InlineScript activities may be critical in certain workflows, they do not support workflow constructs and should only be used when necessary for the following reasons:

  • Non è possibile usare checkpoint all'interno di un blocco InlineScript.You cannot use checkpoints inside an InlineScript block. Se si verifica un errore nel blocco, è necessario riprendere dall'inizio del blocco.If a failure occurs within the block, it must be resumed from the beginning of the block.
  • Non è possibile usare l'esecuzione parallela all'interno di un blocco InlineScriptBlock.You cannot use parallel execution inside an InlineScriptBlock.
  • L'attività InlineScript influisce sulla scalabilità del Runbook perché vincola la sessione di Windows PowerShell per l'intera lunghezza del blocco InlineScript.InlineScript affects scalability of the workflow since it holds the Windows PowerShell session for the entire length of the InlineScript block.

Per altre informazioni sull'uso di InlineScript, vedere Esecuzione dei comandi di Windows PowerShell in un flusso di lavoro e about_InlineScript.For more information on using InlineScript, see Running Windows PowerShell Commands in a Workflow and about_InlineScript.

Elaborazione parallelaParallel processing

Uno dei vantaggi offerti dai flussi di lavoro di Windows PowerShell consiste nella possibilità di eseguire un set di comandi in parallelo anziché in sequenza, come accade invece con uno script tipico.One advantage of Windows PowerShell Workflows is the ability to perform a set of commands in parallel instead of sequentially as with a typical script.

È possibile usare la parola chiave Parallel per creare un blocco di script con più comandi che vengono eseguiti contemporaneamente.You can use the Parallel keyword to create a script block with multiple commands that run concurrently. Viene usata la sintassi indicata di seguito.This uses the following syntax shown below. In questo caso Activity1 e Activity2 iniziano nello stesso momento.In this case, Activity1 and Activity2 starts at the same time. Activity3 viene avviata solo dopo il completamento di Activity1 e Activity2.Activity3 starts only after both Activity1 and Activity2 have completed.

Parallel
{
    <Activity1>
    <Activity2>
}
<Activity3>

Ad esempio, considerare i seguenti comandi PowerShell che consentono di copiare più file in una destinazione di rete.For example, consider the following PowerShell commands that copy multiple files to a network destination. Questi comandi vengono eseguiti in sequenza in modo che finisca la copia di un file prima che venga avviata la successiva.These commands are run sequentially so that one file must finish copying before the next is started.

Copy-Item -Path C:\LocalPath\File1.txt -Destination \\NetworkPath\File1.txt
Copy-Item -Path C:\LocalPath\File2.txt -Destination \\NetworkPath\File2.txt
Copy-Item -Path C:\LocalPath\File3.txt -Destination \\NetworkPath\File3.txt

Nel flusso di lavoro seguente vengono eseguiti questi stessi comandi in parallelo in modo che inizi la copia di tutti nello stesso momento.The following workflow runs these same commands in parallel so that they all start copying at the same time. Solo dopo che la copia è terminata, viene visualizzato il messaggio di completamento.Only after they are all copied is the completion message displayed.

Workflow Copy-Files
{
    Parallel
    {
        Copy-Item -Path "C:\LocalPath\File1.txt" -Destination "\\NetworkPath"
        Copy-Item -Path "C:\LocalPath\File2.txt" -Destination "\\NetworkPath"
        Copy-Item -Path "C:\LocalPath\File3.txt" -Destination "\\NetworkPath"
    }

    Write-Output "Files copied."
}

È possibile usare il costrutto ForEach -Parallel per elaborare i comandi per ogni elemento di una raccolta simultaneamente.You can use the ForEach -Parallel construct to process commands for each item in a collection concurrently. Gli elementi della raccolta vengono elaborati in parallelo, mentre i comandi nel blocco di script vengono eseguiti in sequenza.The items in the collection are processed in parallel while the commands in the script block run sequentially. Viene usata la sintassi indicata di seguito.This uses the following syntax shown below. In questo caso l'avvio di Activity1 è simultaneo a quello di tutti gli altri elementi della raccolta.In this case, Activity1 starts at the same time for all items in the collection. Per ogni elemento, Activity2 inizia al termine di Activity1.For each item, Activity2 starts after Activity1 is complete. Activity3 si avvia solo dopo il completamento di Activity1 e Activity2 per tutti gli elementi.Activity3 starts only after both Activity1 and Activity2 have completed for all items.

ForEach -Parallel ($<item> in $<collection>)
{
    <Activity1>
    <Activity2>
}
<Activity3>

L'esempio seguente è simile all'esempio precedente in cui vengono copiati i file in parallelo.The following example is similar to the previous example copying files in parallel. In questo caso, viene visualizzato un messaggio per ogni file al termine della copia.In this case, a message is displayed for each file after it copies. Solo dopo che stati tutti copiati completamente, viene visualizzato il messaggio di completamento finale.Only after they are all completely copied is the final completion message displayed.

Workflow Copy-Files
{
    $files = @("C:\LocalPath\File1.txt","C:\LocalPath\File2.txt","C:\LocalPath\File3.txt")

    ForEach -Parallel ($File in $Files)
    {
        Copy-Item -Path $File -Destination \\NetworkPath
        Write-Output "$File copied."
    }

    Write-Output "All files copied."
}

Nota

Si sconsiglia l'esecuzione di Runbook figlio in parallelo poiché è stato dimostrato che potrebbe causare risultati inaffidabili.We do not recommend running child runbooks in parallel since this has been shown to give unreliable results. L'output dal runbook figlio talvolta non viene visualizzato e le impostazioni di un runbook figlio possono influire sugli altri runbook figlio paralleli.The output from the child runbook sometimes does not show up, and settings in one child runbook can affect the other parallel child runbooks. È possibile che variabili come $VerbosePreference, $WarningPreference e altre non vengano propagate ai runbook figlio.Variables such as $VerbosePreference, $WarningPreference, and others may not be propagated to the child runbooks. Se poi il runbook figlio modifica questi valori, potrebbe non essere possibile ripristinarli correttamente dopo una chiamata.And if the child runbook changes these values, they may not be properly restored after invocation.

CheckpointCheckpoints

Un checkpoint è uno snapshot dello stato corrente del flusso di lavoro che include il valore corrente per le variabili e gli output generati fino al punto corrispondente.A checkpoint is a snapshot of the current state of the workflow that includes the current value for variables and any output generated to that point. Se un flusso di lavoro termina con errori o viene sospeso, alla successiva esecuzione verrà avviato dall'ultimo checkpoint anziché dall'inizio del flusso di lavoro.If a workflow ends in error or is suspended, then the next time it is run it will start from its last checkpoint instead of the start of the workflow. È possibile impostare un checkpoint in un flusso di lavoro con l'attività Checkpoint-Workflow .You can set a checkpoint in a workflow with the Checkpoint-Workflow activity.

Nel codice di esempio seguente si verifica un'eccezione dopo Activity2 con la conseguente sospensione del Runbook.In the following sample code, an exception occurs after Activity2 causing the workflow to end. Quando il flusso di lavoro viene nuovamente avviato, inizierà con l'esecuzione di Activity2, poiché questa attività si trovava immediatamente dopo l'ultimo checkpoint impostato.When the workflow is run again, it starts by running Activity2 since this was just after the last checkpoint set.

<Activity1>
Checkpoint-Workflow
<Activity2>
<Exception>
<Activity3>

È consigliabile impostare checkpoint in un flusso di lavoro dopo attività che possono essere soggette a eccezioni e che non devono essere ripetute se riprende il flusso di lavoro.You should set checkpoints in a workflow after activities that may be prone to exception and should not be repeated if the workflow is resumed. Si consideri ad esempio un flusso di lavoro con cui viene creata una macchina virtuale.For example, your workflow may create a virtual machine. È possibile impostare un checkpoint sia prima che dopo i comandi di creazione della macchina virtuale.You could set a checkpoint both before and after the commands to create the virtual machine. Se la creazione ha esito negativo, i comandi verrebbero ripetuti se il flusso di lavoro viene riavviato.If the creation fails, then the commands would be repeated if the workflow is started again. Se il flusso di lavoro ha esito negativo dopo il completamento della creazione, la macchina virtuale non verrà creata nuovamente quando verrà ripreso il flusso di lavoro.If the workflow fails after the creation succeeds, then the virtual machine will not be created again when the workflow is resumed.

Nell'esempio seguente vengono copiati più file in un percorso di rete e viene impostato un checkpoint dopo ogni file.The following example copies multiple files to a network location and sets a checkpoint after each file. Se il percorso di rete viene perso, il flusso di lavoro termina con errori.If the network location is lost, then the workflow ends in error. Quando viene avviato nuovamente, verrà ripreso dall'ultimo checkpoint, vale a dire che solo i file che sono già stati copiati vengono ignorati.When it is started again, it will resume at the last checkpoint meaning that only the files that have already been copied are skipped.

Workflow Copy-Files
{
    $files = @("C:\LocalPath\File1.txt","C:\LocalPath\File2.txt","C:\LocalPath\File3.txt")

    ForEach ($File in $Files)
    {
        Copy-Item -Path $File -Destination \\NetworkPath
        Write-Output "$File copied."
        Checkpoint-Workflow
    }

    Write-Output "All files copied."
}

Poiché le credenziali nome utente non vengono rese permanenti dopo la chiamata dell'attività Suspend-Workflow o dopo l'ultimo checkpoint, è necessario impostare le credenziali su Null e quindi recuperarle di nuovo dall'archivio di asset dopo la chiamata di Suspend-Workflow o del checkpoint.Because username credentials are not persisted after you call the Suspend-Workflow activity or after the last checkpoint, you need to set the credentials to null and then retrieve them again from the asset store after Suspend-Workflow or checkpoint is called. In caso contrario, è possibile che venga visualizzato il messaggio di errore seguente: Impossibile riprendere il processo del flusso di lavoro perché i dati di persistenza non sono stati salvati completamente o i dati di persistenza salvati sono danneggiati. È necessario riavviare il flusso di lavoro.Otherwise, you may receive the following error message: The workflow job cannot be resumed, either because persistence data could not be saved completely, or saved persistence data has been corrupted. You must restart the workflow.

Il codice seguente mostra come gestire questa situazione nei runbook del flusso di lavoro di PowerShell.The following same code demonstrates how to handle this in your PowerShell Workflow runbooks.

workflow CreateTestVms
{
    $Cred = Get-AzureAutomationCredential -Name "MyCredential"
    $null = Connect-AzureRmAccount -Credential $Cred

    $VmsToCreate = Get-AzureAutomationVariable -Name "VmsToCreate"

    foreach ($VmName in $VmsToCreate)
        {
        # Do work first to create the VM (code not shown)

        # Now add the VM
        New-AzureRmVm -VM $Vm -Location "WestUs" -ResourceGroupName "ResourceGroup01"

        # Checkpoint so that VM creation is not repeated if workflow suspends
        $Cred = $null
        Checkpoint-Workflow
        $Cred = Get-AzureAutomationCredential -Name "MyCredential"
        $null = Connect-AzureRmAccount -Credential $Cred
        }
}

Importante

Add-AzureRmAccount è ora un alias per Connect-AzureRMAccount.Add-AzureRmAccount is now an alias for Connect-AzureRMAccount. Quando si esegue la ricerca tra gli elementi della libreria, se Connect-AzureRMAccount non viene visualizzato, è possibile usare Add-AzureRmAccount oppure aggiornare i moduli nell'account di Automazione.When searching your library items, if you do not see Connect-AzureRMAccount, you can use Add-AzureRmAccount, or you can update your modules in your Automation Account.

Ciò non è necessario se si esegue l'autenticazione usando un account RunAs configurato con un'entità servizio.This is not required if you are authenticating using a Run As account configured with a service principal.

Per altre informazioni sui checkpoint, vedere l'articolo relativo all' aggiunta di checkpoint a un flusso di lavoro di script.For more information about checkpoints, see Adding Checkpoints to a Script Workflow.

Passaggi successiviNext steps