Aprenda o fluxo de trabalho do PowerShell para automação do Azure

Os runbooks na Automação do Azure são implementados como fluxos de trabalho do Windows PowerShell, scripts do Windows PowerShell que usam o Windows Workflow Foundation. Um fluxo de trabalho é uma sequência de passos programados e ligados que efetuam tarefas de longa execução ou requerem a coordenação de vários passos em vários dispositivos ou nós geridos.

Enquanto um fluxo de trabalho é escrito com sintaxe do Windows PowerShell e iniciado pelo Windows PowerShell, ele é processado pelo Windows Workflow Foundation. Os benefícios de um fluxo de trabalho em relação a um script normal incluem o desempenho simultâneo de uma ação contra vários dispositivos e a recuperação automática de falhas.

Nota

Este artigo é aplicável ao PowerShell 5.1; O PowerShell 7.1 (visualização) e o PowerShell 7.2 (visualização) não oferecem suporte a fluxos de trabalho. Um script de fluxo de trabalho do PowerShell é muito semelhante a um script do Windows PowerShell, mas tem algumas diferenças significativas que podem ser confusas para um novo usuário. Portanto, recomendamos que você escreva seus runbooks usando o Fluxo de Trabalho do PowerShell somente se precisar usar pontos de verificação.

Para obter detalhes completos dos tópicos deste artigo, consulte Introdução ao fluxo de trabalho do Windows PowerShell.

Usar palavra-chave Fluxo de trabalho

A primeira etapa para converter um script do PowerShell em um fluxo de trabalho do PowerShell é incluí-lo com a Workflow palavra-chave. Um fluxo de trabalho começa com a Workflow palavra-chave seguida pelo corpo do script entre chaves. O nome do fluxo de trabalho segue a palavra-chave conforme mostrado na sintaxe a Workflow seguir:

Workflow Test-Workflow
{
    <Commands>
}

O nome do fluxo de trabalho deve corresponder ao nome do runbook de automação. Se o runbook estiver sendo importado, o nome do arquivo deverá corresponder ao nome do fluxo de trabalho e terminará em .ps1.

Para adicionar parâmetros ao fluxo de trabalho, use a Param palavra-chave exatamente como faria em um script.

Saiba as diferenças entre o código de fluxo de trabalho do PowerShell e o código de script do PowerShell

O código do Fluxo de Trabalho do PowerShell parece quase idêntico ao código de script do PowerShell, exceto por algumas alterações significativas. As seções a seguir descrevem as alterações que você precisa fazer em um script do PowerShell para que ele seja executado em um fluxo de trabalho.

Atividades

Uma atividade é uma tarefa específica em um fluxo de trabalho que é executada em uma sequência. O Fluxo de Trabalho do Windows PowerShell converte automaticamente muitos dos cmdlets do Windows PowerShell em atividades quando executa um fluxo de trabalho. Quando você especifica um desses cmdlets em seu runbook, a atividade correspondente é executada pelo Windows Workflow Foundation.

Se um cmdlet não tiver nenhuma atividade correspondente, o Fluxo de Trabalho do Windows PowerShell executará automaticamente o cmdlet em uma atividade InlineScript . Alguns cmdlets são excluídos e não podem ser usados em um fluxo de trabalho, a menos que você os inclua explicitamente em um bloco InlineScript. Para obter mais informações, consulte Usando atividades em fluxos de trabalho de script.

As atividades de fluxo de trabalho compartilham um conjunto de parâmetros comuns para configurar sua operação. Ver about_WorkflowCommonParameters.

Parâmetros posicionais

Não é possível usar parâmetros posicionais com atividades e cmdlets em um fluxo de trabalho. Portanto, você deve usar nomes de parâmetro. Considere o seguinte código que obtém todos os serviços em execução:

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

Se você tentar executar esse código em um fluxo de trabalho, receberá uma mensagem como Para corrigir esse problema, forneça o nome do parâmetro, como Parameter set cannot be resolved using the specified named parameters. no exemplo a seguir:

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

Objetos desserializados

Os objetos em fluxos de trabalho são desserializados, o que significa que suas propriedades ainda estão disponíveis, mas não seus métodos. Por exemplo, considere o seguinte código do PowerShell, que interrompe um serviço usando o StopService método do objeto.

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

Se você tentar executar isso em um fluxo de trabalho, receberá um erro dizendo Method invocation is not supported in a Windows PowerShell Workflow.

Uma opção é encapsular essas duas linhas de código em um bloco InlineScript . Nesse caso, Service representa um objeto de serviço dentro do bloco .

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

Outra opção é usar outro cmdlet que tenha a mesma funcionalidade do método, se houver um disponível. Em nosso exemplo, o cmdlet fornece a mesma funcionalidade que o método, e você pode usar o Stop-ServiceStop código a seguir para um fluxo de trabalho.

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

Usar InlineScript

AInlineScript atividade é útil quando você precisa executar um ou mais comandos como script tradicional do PowerShell em vez do fluxo de trabalho do PowerShell. Enquanto os comandos em um fluxo de trabalho são enviados ao Windows Workflow Foundation para processamento, os comandos em um bloco InlineScript são processados pelo Windows PowerShell.

InlineScript usa a sintaxe a seguir mostrada abaixo.

InlineScript
{
    <Script Block>
} <Common Parameters>

Você pode retornar a saída de um InlineScript atribuindo a saída a uma variável. O exemplo a seguir interrompe um serviço e, em seguida, gera a saída do nome do serviço.

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

    $Output.Name
}

Você pode passar valores para um bloco InlineScript, mas deve usar $Using modificador de escopo. O exemplo a seguir é idêntico ao exemplo anterior, exceto que o nome do serviço é fornecido por uma variável.

Workflow Stop-MyService
{
    $ServiceName = "MyService"

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

    $Output.Name
}

Embora as atividades InlineScript possam ser críticas em determinados fluxos de trabalho, elas não oferecem suporte a construções de fluxo de trabalho. Deve utilizá-los apenas quando necessário pelas seguintes razões:

  • Não é possível usar pontos de verificação dentro de um bloco InlineScript. Se ocorrer uma falha dentro do bloco, ele deve ser retomado desde o início do bloco.
  • Não é possível usar a execução paralela dentro de um bloco InlineScript.
  • InlineScript afeta a escalabilidade do fluxo de trabalho, uma vez que mantém a sessão do Windows PowerShell durante todo o comprimento do bloco InlineScript.

Para obter mais informações sobre como usar o InlineScript, consulte Executando comandos do Windows PowerShell em um fluxo de trabalho e about_InlineScript.

Usar processamento paralelo

Uma vantagem dos Fluxos de Trabalho do Windows PowerShell é a capacidade de executar um conjunto de comandos em paralelo em vez de sequencialmente, como acontece com um script típico.

Você pode usar a Parallel palavra-chave para criar um bloco de script com vários comandos que são executados simultaneamente. Isso usa a sintaxe a seguir mostrada abaixo. Neste caso, a Atividade1 e a Atividade2 começam ao mesmo tempo. A Atividade3 só começa após a conclusão da Atividade1 e da Atividade2.

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

Por exemplo, considere os seguintes comandos do PowerShell que copiam vários arquivos para um destino de rede. Esses comandos são executados sequencialmente para que um arquivo deve terminar de copiar antes que o próximo seja iniciado.

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

O fluxo de trabalho a seguir executa esses mesmos comandos em paralelo para que todos comecem a copiar ao mesmo tempo. Só depois de todos serem copiados é que a mensagem de conclusão é apresentada.

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."
}

Você pode usar a ForEach -Parallel construção para processar comandos para cada item em uma coleção simultaneamente. Os itens na coleção são processados em paralelo, enquanto os comandos no bloco de script são executados sequencialmente. Esse processo usa a seguinte sintaxe mostrada abaixo. Nesse caso, a Atividade1 começa ao mesmo tempo para todos os itens da coleção. Para cada item, a Atividade2 começa após a conclusão da Atividade1. A Atividade3 só começa após a conclusão da Atividade1 e da Atividade2 para todos os itens. Usamos o parâmetro para limitar o ThrottleLimit paralelismo. Muito alto de um ThrottleLimit pode causar problemas. O valor ideal para o parâmetro depende de ThrottleLimit muitos fatores em seu ambiente. Comece com um valor baixo e tente diferentes valores crescentes até encontrar um que funcione para a sua circunstância específica.

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

O exemplo a seguir é semelhante ao exemplo anterior copiando arquivos em paralelo. Nesse caso, uma mensagem é exibida para cada arquivo depois que ele copia. Só depois de todos serem copiados é que é apresentada a mensagem de conclusão final.

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

Não recomendamos a execução de runbooks infantis em paralelo, uma vez que isso demonstrou dar resultados não confiáveis. A saída do runbook filho às vezes não aparece, e as configurações em um runbook filho podem afetar os outros runbooks filho paralelos. Variáveis como VerbosePreference, WarningPreferencee outras podem não se propagar para os runbooks filho. E se o runbook filho alterar esses valores, eles podem não ser restaurados corretamente após a invocação.

Usar pontos de verificação em um fluxo de trabalho

Um ponto de verificação é um instantâneo do estado atual do fluxo de trabalho que inclui os valores atuais para variáveis e qualquer saída gerada até esse ponto. Se um fluxo de trabalho terminar em erro ou for suspenso, ele começará a partir de seu último ponto de verificação na próxima vez que for executado, em vez de começar no início.

Você pode definir um ponto de verificação em um fluxo de trabalho com a Checkpoint-Workflow atividade. A Automação do Azure tem um recurso chamado fair share, para o qual qualquer runbook executado por três horas é descarregado para permitir que outros runbooks sejam executados. Eventualmente, o runbook descarregado é recarregado. Quando está, ele retoma a execução a partir do último ponto de verificação tomado no runbook.

Para garantir que o runbook seja concluído, você deve adicionar pontos de verificação em intervalos que são executados por menos de três horas. Se durante cada execução um novo ponto de verificação for adicionado, e se o runbook for removido após três horas devido a um erro, o runbook será retomado indefinidamente.

No exemplo a seguir, uma exceção ocorre após Activity2, fazendo com que o fluxo de trabalho termine. Quando o fluxo de trabalho é executado novamente, ele começa executando Activity2, já que essa atividade foi logo após o último ponto de verificação definido.

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

Defina pontos de verificação em um fluxo de trabalho após atividades que podem ser propensas a exceções e não devem ser repetidas se o fluxo de trabalho for retomado. Por exemplo, seu fluxo de trabalho pode criar uma máquina virtual. Você pode definir um ponto de verificação antes e depois dos comandos para criar a máquina virtual. Se a criação falhar, os comandos serão repetidos se o fluxo de trabalho for iniciado novamente. Se o fluxo de trabalho falhar após a criação bem-sucedida, a máquina virtual não será criada novamente quando o fluxo de trabalho for retomado.

O exemplo a seguir copia vários arquivos para um local de rede e define um ponto de verificação após cada arquivo. Se o local de rede for perdido, o fluxo de trabalho terminará em erro. Quando é reiniciado, é retomado no último ponto de verificação. Somente os arquivos que já foram copiados são ignorados.

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 as credenciais de nome de usuário não são persistentes depois que você chama a atividade Suspend-Workflow ou após o último ponto de verificação, você precisa definir as credenciais como nulas e, em seguida, recuperá-las novamente do repositório de ativos depois Suspend-Workflow que o ponto de verificação for chamado. Caso contrário, poderá receber a seguinte mensagem de erro: 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.

O mesmo código a seguir demonstra como lidar com essa situação em seus runbooks de fluxo de trabalho do PowerShell.

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

Para runbooks não gráficos do PowerShell, Add-AzAccount e Add-AzureRMAccount são aliases para Connect-AzAccount. Você pode usar esses cmdlets ou atualizar seus módulos em sua conta de automação para as versões mais recentes. Talvez seja necessário atualizar seus módulos mesmo que tenha acabado de criar uma nova conta de automação.

Para obter mais informações sobre pontos de verificação, consulte Adicionando pontos de verificação a um fluxo de trabalho de script.

Próximos passos

  • Para saber mais sobre os runbooks do Fluxo de Trabalho do PowerShell, consulte Tutorial: Criar um runbook do Fluxo de Trabalho do PowerShell.