Información sobre el flujo de trabajo de PowerShell para Azure AutomationLearn PowerShell Workflow for Azure Automation

Los runbooks de Azure Automation se implementan como flujos de trabajo de Windows PowerShell, scripts de Windows PowerShell que usan Windows Workflow Foundation.Runbooks in Azure Automation are implemented as Windows PowerShell workflows, Windows PowerShell scripts that use Windows Workflow Foundation. Un flujo de trabajo es una secuencia de pasos conectados y programados que realizan tareas de larga duración o requieren de la coordinación de pasos múltiples a través de varios dispositivos o nodos administrados.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.

Aunque el flujo de trabajo esté escrito con sintaxis de Windows PowerShell y se inicie mediante Windows PowerShell, se procesa mediante Windows Workflow Foundation.While a workflow is written with Windows PowerShell syntax and launched by Windows PowerShell, it is processed by Windows Workflow Foundation. Las ventajas de un flujo de trabajo en un script normal incluyen el rendimiento simultáneo de una acción en varios dispositivos y la recuperación automática en caso de errores.The benefits of a workflow over a normal script include simultaneous performance of an action against multiple devices and automatic recovery from failures.

Nota

Un flujo de trabajo de PowerShell es muy similar a un script de Windows PowerShell, pero presenta algunas diferencias importantes que pueden resultar confusas para un nuevo usuario.A PowerShell Workflow script is very similar to a Windows PowerShell script but has some significant differences that can be confusing to a new user. Por lo tanto, se recomienda escribir los runbooks con el flujo de trabajo de PowerShell solo si hay que usar puntos de control.Therefore, we recommend that you write your runbooks using PowerShell Workflow only if you need to use checkpoints.

Para más información sobre los temas de este artículo, consulte Introducción al flujo de trabajo de Windows PowerShell.For complete details of the topics in this article, see Getting Started with Windows PowerShell Workflow.

Uso de la palabra clave workflowUse Workflow keyword

El primer paso para convertir un script de PowerShell en un flujo de trabajo de PowerShell es delimitarlo con la palabra clave Workflow.The first step to converting a PowerShell script to a PowerShell workflow is enclosing it with the Workflow keyword. Un flujo de trabajo comienza con la palabra clave Workflow, seguida del cuerpo del script entre llaves.A workflow starts with the Workflow keyword followed by the body of the script enclosed in braces. El nombre del flujo de trabajo sigue a la palabra clave Workflow, tal y como se muestra en la sintaxis siguiente:The name of the workflow follows the Workflow keyword as shown in the following syntax:

Workflow Test-Workflow
{
    <Commands>
}

El nombre del flujo de trabajo debe coincidir con el nombre del runbook de Automation.The name of the workflow must match the name of the Automation runbook. Si se va a importar el runbook, el nombre de archivo debe coincidir con el nombre del flujo de trabajo y debe terminar en .ps1.If the runbook is being imported, then the file name must match the workflow name and must end in .ps1.

Para agregar parámetros al flujo de trabajo, use la palabra clave Param igual que lo haría en un script.To add parameters to the workflow, use the Param keyword just as you would in a script.

Información sobre las diferencias entre el código de flujo de trabajo de PowerShell y el código de script de PowerShellLearn differences between PowerShell Workflow code and PowerShell script code

El código de flujo de trabajo de PowerShell es casi idéntico al código de script de PowerShell salvo por algunos cambios importantes.PowerShell Workflow code looks almost identical to PowerShell script code except for a few significant changes. En las secciones siguientes se describen los cambios que debe realizar en un script de PowerShell para que se ejecute en un flujo de trabajo.The following sections describe changes that you need to make to a PowerShell script for it to run in a workflow.

ActividadesActivities

Una actividad es una tarea específica en un flujo de trabajo que se realiza en una secuencia.An activity is a specific task in a workflow that is performed in a sequence. El flujo de trabajo de Windows PowerShell convierte automáticamente muchos de los cmdlets de Windows PowerShell en actividades cuando se ejecuta un flujo de trabajo.Windows PowerShell Workflow automatically converts many of the Windows PowerShell cmdlets to activities when it runs a workflow. Cuando se especifica uno de estos cmdlets en el runbook, Windows Workflow Foundation ejecuta la actividad correspondiente.When you specify one of these cmdlets in your runbook, the corresponding activity is run by Windows Workflow Foundation.

Para los cmdlets sin actividad correspondiente, el flujo de trabajo de Windows PowerShell ejecuta automáticamente el cmdlet en una actividad InlineScript.If a cmdlet has no corresponding activity, Windows PowerShell Workflow automatically runs the cmdlet in an InlineScript activity. Algunos cmdlets están excluidos y no se pueden usar en un flujo de trabajo a menos que se incluyan explícitamente en un bloque de InlineScript.Some cmdlets are excluded and can't be used in a workflow unless you explicitly include them in an InlineScript block. Para más información, consulte Uso de actividades en flujos de trabajo de script.For more information, see Using Activities in Script Workflows.

Las actividades de flujo de trabajo comparten un conjunto de parámetros comunes para configurar su funcionamiento.Workflow activities share a set of common parameters to configure their operation. Consulte about_WorkflowCommonParameters.See about_WorkflowCommonParameters.

Parámetros posicionalesPositional parameters

No puede usar parámetros posicionales con actividades y cmdlets en un flujo de trabajo.You can't use positional parameters with activities and cmdlets in a workflow. Por lo tanto, debe usar nombres de parámetro.Therefore, you must use parameter names. Considere el siguiente código que obtiene todos los servicios en ejecución:Consider the following code that gets all running services:

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

Si intenta ejecutar este código en un flujo de trabajo, recibirá un mensaje similar a Parameter set cannot be resolved using the specified named parameters.. Para corregir este problema, proporcione el nombre del parámetro, como en el ejemplo siguiente:If you try to run this code in a workflow, you receive a message like Parameter set cannot be resolved using the specified named parameters. To correct for this issue, provide the parameter name, as in the following example:

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

Objetos deserializadosDeserialized objects

Los objetos de los flujos de trabajo se deserializan, lo que significa que sus propiedades siguen estando disponibles, pero no sus métodos.Objects in workflows are deserialized, meaning that their properties are still available, but not their methods. Por ejemplo, considere el siguiente código de PowerShell, que detiene un servicio con el método Stop del objeto Service.For example, consider the following PowerShell code, which stops a service using the Stop method of the Service object.

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

Si intenta ejecutarlo en un flujo de trabajo, recibirá un error que indica Method invocation is not supported in a Windows PowerShell Workflow..If you try to run this in a workflow, you receive an error saying Method invocation is not supported in a Windows PowerShell Workflow.

Una opción es ajustar estas dos líneas de código en un bloque de InlineScript.One option is to wrap these two lines of code in an InlineScript block. En este caso, Service representa un objeto de servicio dentro del bloque.In this case, Service represents a service object within the block.

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

Otra opción es usar otro cmdlet que tenga la misma funcionalidad que el método, si hay uno disponible.Another option is to use another cmdlet that has the same functionality as the method, if one is available. En nuestro ejemplo, el cmdlet Stop-Service proporciona la misma funcionalidad que el método Stop, y se podría usar el siguiente código para un flujo de trabajo.In our example, the Stop-Service cmdlet provides the same functionality as the Stop method, and you might use the following code for a workflow.

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

Uso de InlineScriptUse InlineScript

La actividad InlineScript es útil cuando necesita ejecutar uno o más comandos como un script tradicional de PowerShell en lugar de como un flujo de trabajo de PowerShell.TheInlineScript activity is useful when you need to run one or more commands as traditional PowerShell script instead of PowerShell workflow. Mientras que los comandos de un flujo de trabajo se envían a Windows Workflow Foundation para su procesamiento, los comandos de un bloque de InlineScript se procesan mediante 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 sintaxis que se muestra a continuación.InlineScript uses the following syntax shown below.

InlineScript
{
    <Script Block>
} <Common Parameters>

Puede devolver resultados de InlineScript asignando el resultado a una variable.You can return output from an InlineScript by assigning the output to a variable. El siguiente ejemplo detiene un servicio y, a continuación, envía el nombre de servicio.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
}

Puede pasar valores en un bloque de InlineScript, pero debe usar el modificador de ámbito $Using .You can pass values into an InlineScript block, but you must use $Using scope modifier. El ejemplo siguiente es idéntico al ejemplo anterior salvo que se proporciona el nombre de servicio mediante una variable.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
}

Aunque las actividades InlineScript puedan ser críticas en determinados flujos de trabajo, no admiten construcciones de flujo de trabajo.While InlineScript activities might be critical in certain workflows, they do not support workflow constructs. Solo debe usarlos cuando sea necesario por los siguientes motivos:You should use them only when necessary for the following reasons:

  • No puede usar puntos de control dentro de un bloque de InlineScript.You can't use checkpoints inside an InlineScript block. Si se produce un error dentro del bloque, se debe reanudar desde el principio del bloque.If a failure occurs within the block, it must resume from the beginning of the block.
  • No puede usar la ejecución en paralelo dentro de un bloque de InlineScript.You can't use parallel execution inside an InlineScript block.
  • InlineScript afecta a la escalabilidad del flujo de trabajo, ya que retiene la sesión de Windows PowerShell durante todo el bloque de InlineScript.InlineScript affects scalability of the workflow since it holds the Windows PowerShell session for the entire length of the InlineScript block.

Para más información sobre el uso de InlineScript, vea Ejecutar comandos de Windows PowerShell en un flujo de trabajo y about_InlineScript.For more information on using InlineScript, see Running Windows PowerShell Commands in a Workflow and about_InlineScript.

Uso del procesamiento paraleloUse parallel processing

Una ventaja de los flujos de trabajo de Windows PowerShell es la capacidad para realizar un conjunto de comandos en paralelo en lugar de hacerlo secuencialmente como con un script típico.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.

Puede usar la palabra clave Parallel para crear un bloque de scripts con varios comandos que se ejecutan simultáneamente.You can use the Parallel keyword to create a script block with multiple commands that run concurrently. Esto usa la siguiente sintaxis que se muestra a continuación.This uses the following syntax shown below. En este caso, Activity1 y Activity2 se inician al mismo tiempo.In this case, Activity1 and Activity2 starts at the same time. Activity3 se inicia después de que se hayan completado Activity1 y Activity2.Activity3 starts only after both Activity1 and Activity2 have completed.

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

Por ejemplo, considere los siguientes comandos de PowerShell que copian varios archivos a un destino de red.For example, consider the following PowerShell commands that copy multiple files to a network destination. Estos comandos se ejecutan secuencialmente de modo que un archivo debe terminar de copiarse antes de que comience el siguiente.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

El flujo de trabajo siguiente ejecuta estos mismos comandos en paralelo para que todos ellos empiezan a copiarse al mismo tiempo.The following workflow runs these same commands in parallel so that they all start copying at the same time. Una vez que todos se han copiado, se muestra el mensaje de finalización.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."
}

Puede utilizar la construcción ForEach -Parallel para procesar comandos para cada elemento de una colección simultáneamente.You can use the ForEach -Parallel construct to process commands for each item in a collection concurrently. Los elementos de la colección se procesan en paralelo mientras que los comandos del bloque de scripts se ejecutan secuencialmente.The items in the collection are processed in parallel while the commands in the script block run sequentially. Este proceso usa la siguiente sintaxis que se muestra a continuación.This process uses the following syntax shown below. En este caso, Activity1 se inicia al mismo tiempo para todos los elementos de la colección.In this case, Activity1 starts at the same time for all items in the collection. Para cada elemento, Activity2 se inicia una vez completado Activity1.For each item, Activity2 starts after Activity1 is complete. Activity3 se inicia únicamente después de que se hayan completado Activity1 y Activity2 para todos los elementos.Activity3 starts only after both Activity1 and Activity2 have completed for all items. Se usa el parámetro ThrottleLimit para limitar el paralelismo.We use the ThrottleLimit parameter to limit the parallelism. Un valor ThrottleLimit demasiado alto puede causar problemas.Too high of a ThrottleLimit can cause problems. El valor ideal para el parámetro ThrottleLimit depende de muchos factores del entorno.The ideal value for the ThrottleLimit parameter depends on many factors in your environment. Empiece con un valor bajo y pruebe distintos valores crecientes hasta que encuentre uno que funcione para su caso concreto.Start with a low value and try different increasing values until you find one that works for your specific circumstance.

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

El ejemplo siguiente es similar al ejemplo anterior, en el que se copian archivos en paralelo.The following example is similar to the previous example copying files in parallel. En este caso, se muestra un mensaje para cada archivo después de copiarse.In this case, a message is displayed for each file after it copies. Una vez que todos se han copiado, se muestra el mensaje de finalización.Only after they are all 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 -ThrottleLimit 10 ($File in $Files)
    {
        Copy-Item -Path $File -Destination \\NetworkPath
        Write-Output "$File copied."
    }

    Write-Output "All files copied."
}

Nota

No se recomienda ejecutar runbooks secundarios en paralelo, ya que se ha demostrado que no tiene unos resultados confiables.We do not recommend running child runbooks in parallel since this has been shown to give unreliable results. A veces el resultado del runbook secundario no se muestra, y la configuración de un runbook secundario puede afectar a los demás runbooks secundarios paralelos.The output from the child runbook sometimes does not show up, and settings in one child runbook can affect the other parallel child runbooks. Variables tales como VerbosePreference, WarningPreference y otras podrían no propagarse a los runbooks secundarios.Variables such as VerbosePreference, WarningPreference, and others might not propagate to the child runbooks. Y si el runbook secundario cambia estos valores, es posible que no se restauren correctamente después de su invocación.And if the child runbook changes these values, they might not be properly restored after invocation.

Uso de puntos de control en un flujo de trabajoUse checkpoints in a workflow

Un punto de control es una instantánea del estado actual del flujo de trabajo que incluye el valor actual de las variables y cualquier salida generada en ese punto.A checkpoint is a snapshot of the current state of the workflow that includes the current values for variables and any output generated to that point. Si un flujo de trabajo termina en error o se suspende, comienza desde su último punto de control la próxima vez que se ejecute, en lugar de comenzar desde el principio.If a workflow ends in error or is suspended, it starts from its last checkpoint the next time it runs, instead of starting at the beginning.

Puede establecer un punto de control en un flujo de trabajo con la actividad Checkpoint-Workflow.You can set a checkpoint in a workflow with the Checkpoint-Workflow activity. Azure Automation tiene una característica denominada distribución equilibrada, por la que se descarga cualquier runbook que se ejecute durante tres horas para permitir la ejecución de otros runbooks.Azure Automation has a feature called fair share, for which any runbook that runs for three hours is unloaded to allow other runbooks to run. Finalmente, se recarga el runbook descargado.Eventually, the unloaded runbook is reloaded. Cuando es así, se reanuda la ejecución desde el último punto de control tomado en el runbook.When it is, it resumes execution from the last checkpoint taken in the runbook.

Con el fin de garantizar que el runbook finalmente se complete, debe agregar puntos de control en intervalos que se ejecuten durante menos de tres horas.To guarantee that the runbook eventually completes, you must add checkpoints at intervals that run for less than three hours. Si durante cada ejecución se agrega un nuevo punto de control, y si el runbook se expulsa después de tres horas debido a un error, el runbook se reanudará indefinidamente.If during each run a new checkpoint is added, and if the runbook is evicted after three hours due to an error, the runbook is resumed indefinitely.

En el ejemplo siguiente, se produce una excepción después de Activity2, lo que provoca la finalización del flujo de trabajo.In the following example, an exception occurs after Activity2, causing the workflow to end. Cuando se vuelve a ejecutar el flujo de trabajo, se inicia ejecutando Activity2, ya que estaba inmediatamente después del último punto de control establecido.When the workflow is run again, it starts by running Activity2, since this activity was just after the last checkpoint set.

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

Establezca puntos de control en un flujo de trabajo después de actividades que puedan ser propensas a la excepción y que no deben repetirse si se reanuda el flujo de trabajo.Set checkpoints in a workflow after activities that might be prone to exception and should not be repeated if the workflow is resumed. Por ejemplo, el flujo de trabajo puede crear una máquina virtual.For example, your workflow might create a virtual machine. Puede establecer un punto de control antes y después de los comandos para crear la máquina virtual.You can set a checkpoint both before and after the commands to create the virtual machine. Si se produce un error en la creación, los comandos se repiten si el flujo de trabajo se vuelve a iniciar.If the creation fails, then the commands are repeated if the workflow is started again. Si el flujo de trabajo produce un error después de que la creación se realice correctamente, la máquina virtual no se vuelve a crear cuando se reanude el flujo de trabajo.If the workflow fails after the creation succeeds, the virtual machine is not created again when the workflow is resumed.

El siguiente ejemplo copia varios archivos en una ubicación de red y establece un punto de comprobación después de cada archivo.The following example copies multiple files to a network location and sets a checkpoint after each file. Si la ubicación de red se pierde, el flujo de trabajo finaliza con error.If the network location is lost, then the workflow ends in error. Cuando se vuelve a iniciar, se reanuda en el último punto de control.When it is started again, it resumes at the last checkpoint. Solo se omiten los archivos que ya se han copiado.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."
}

Como las credenciales de nombre de usuario no se conservan después de llamar a la actividad Suspend-Workflow o después del último punto de control, tiene que establecer las credenciales en NULL y, después, recuperarlas de nuevo desde el almacén de recursos tras llamar a Suspend-Workflow o al punto de control.Because user name 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. En caso contrario, es posible que reciba el siguiente mensaje de error: 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..Otherwise, you might 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.

El mismo código de abajo muestra cómo controlar esta operación en los runbooks del flujo de trabajo de PowerShell.The following same code demonstrates how to handle this situation in your PowerShell Workflow runbooks.

workflow CreateTestVms
{
    $Cred = Get-AzAutomationCredential -Name "MyCredential"
    $null = Connect-AzAccount -Credential $Cred

    $VmsToCreate = Get-AzAutomationVariable -Name "VmsToCreate"

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

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

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

Nota

En el caso de los runbooks de PowerShell no gráficos, Add-AzAccount y Add-AzureRMAccount son alias de Connect-AzAccount.For non-graphical PowerShell runbooks, Add-AzAccount and Add-AzureRMAccount are aliases for Connect-AzAccount. Puede usar estos cmdlets o bien actualizar los módulos de la cuenta de Automation a las versiones más recientes.You can use these cmdlets or you can update your modules in your Automation account to the latest versions. Es posible que deba actualizar los módulos incluso si acaba de crear una nueva cuenta de Automation.You might need to update your modules even if you have just created a new Automation account. El uso de estos cmdlets no es necesario si se autentica utilizando una cuenta de ejecución configurada con una entidad de servicio.Use of these cmdlets is not required if you are authenticating using a Run As account configured with a service principal.

Para obtener más información acerca de los puntos de control, consulte Adición de puntos de control a un flujo de trabajo de scripts.For more information about checkpoints, see Adding Checkpoints to a Script Workflow.

Pasos siguientesNext steps