PowerShell-werkstroom voor Azure Automation leren

Runbooks in Azure Automation worden geïmplementeerd als Windows PowerShell-werkstromen, Windows PowerShell-scripts die gebruikmaken van Windows Workflow Foundation. Een werkstroom is een opeenvolging van geprogrammeerde, met elkaar verbonden stappen waarmee langlopende taken worden uitgevoerd of die de coördinatie vereisen van meerdere stappen op meerdere apparaten of beheerde knooppunten.

Hoewel een werkstroom is geschreven met de syntaxis van Windows PowerShell en wordt gestart door Windows PowerShell, wordt deze verwerkt door Windows Workflow Foundation. De voordelen van een werkstroom ten opzichte van een normaal script zijn gelijktijdige prestaties van een actie op meerdere apparaten en automatisch herstel na fouten.

Notitie

Dit artikel is van toepassing op PowerShell 5.1; PowerShell 7.1 (preview) en PowerShell 7.2 (preview) bieden geen ondersteuning voor werkstromen. Een PowerShell Workflow-script is vergelijkbaar met een Windows PowerShell-script, maar heeft enkele belangrijke verschillen die verwarrend kunnen zijn voor een nieuwe gebruiker. Daarom raden we u aan uw runbooks alleen te schrijven met Behulp van PowerShell Workflow als u controlepunten moet gebruiken.

Zie Aan de slag met Windows PowerShell Workflow voor meer informatie over de onderwerpen in dit artikel.

Werkstroomwoord gebruiken

De eerste stap voor het converteren van een PowerShell-script naar een PowerShell-werkstroom is het insluiten van het Workflow trefwoord. Een werkstroom begint met het Workflow trefwoord gevolgd door de hoofdtekst van het script tussen accolades. De naam van de werkstroom volgt het Workflow trefwoord, zoals wordt weergegeven in de volgende syntaxis:

Workflow Test-Workflow
{
    <Commands>
}

De naam van de werkstroom moet overeenkomen met de naam van het Automation-runbook. Als het runbook wordt geïmporteerd, moet de bestandsnaam overeenkomen met de naam van de werkstroom en eindigen op .ps1.

Als u parameters aan de werkstroom wilt toevoegen, gebruikt u het Param trefwoord op dezelfde wijze als in een script.

Meer informatie over verschillen tussen PowerShell Workflow-code en PowerShell-scriptcode

PowerShell Workflow-code lijkt bijna identiek aan PowerShell-scriptcode, met uitzondering van enkele belangrijke wijzigingen. In de volgende secties worden wijzigingen beschreven die u moet aanbrengen in een PowerShell-script om deze in een werkstroom uit te voeren.

Activiteiten

Een activiteit is een specifieke taak in een werkstroom die in een reeks wordt uitgevoerd. Windows PowerShell Workflow converteert automatisch veel van de Windows PowerShell-cmdlets naar activiteiten wanneer een werkstroom wordt uitgevoerd. Wanneer u een van deze cmdlets opgeeft in uw runbook, wordt de bijbehorende activiteit uitgevoerd door Windows Workflow Foundation.

Als een cmdlet geen bijbehorende activiteit heeft, voert Windows PowerShell Workflow de cmdlet automatisch uit in een InlineScript-activiteit . Sommige cmdlets worden uitgesloten en kunnen niet worden gebruikt in een werkstroom, tenzij u ze expliciet in een InlineScript-blok opneemt. Zie Activiteiten gebruiken in scriptwerkstromen voor meer informatie.

Werkstroomactiviteiten delen een set algemene parameters om hun bewerking te configureren. Zie about_WorkflowCommonParameters.

Positionele parameters

U kunt geen positionele parameters gebruiken met activiteiten en cmdlets in een werkstroom. Daarom moet u parameternamen gebruiken. Houd rekening met de volgende code waarmee alle actieve services worden uitgevoerd:

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

Als u deze code probeert uit te voeren in een werkstroom, ontvangt u een bericht zoals Parameter set cannot be resolved using the specified named parameters. U kunt corrigeren voor dit probleem, geeft u de parameternaam op, zoals in het volgende voorbeeld:

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

Gedeserialiseerde objecten

Objecten in werkstromen worden gedeserialiseerd, wat betekent dat hun eigenschappen nog steeds beschikbaar zijn, maar niet hun methoden. Denk bijvoorbeeld aan de volgende PowerShell-code, waarmee een service wordt gestopt met behulp van de Stop methode van het Service object.

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

Als u dit probeert uit te voeren in een werkstroom, wordt er een foutbericht weergegeven met de mededeling Method invocation is not supported in a Windows PowerShell Workflow.

Een optie is om deze twee regels code in een InlineScript-blok te verpakken. In dit geval Service vertegenwoordigt u een serviceobject in het blok.

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

Een andere optie is om een andere cmdlet te gebruiken die dezelfde functionaliteit heeft als de methode, als deze beschikbaar is. In ons voorbeeld biedt de Stop-Service cmdlet dezelfde functionaliteit als de Stop methode. U kunt de volgende code voor een werkstroom gebruiken.

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

InlineScript gebruiken

DeInlineScript activiteit is handig wanneer u een of meer opdrachten als traditioneel PowerShell-script moet uitvoeren in plaats van powershell-werkstroom. Opdrachten in een werkstroom worden verzonden naar Windows Workflow Foundation voor verwerking, maar opdrachten in een InlineScript-blok worden verwerkt door Windows PowerShell.

InlineScript gebruikt de volgende syntaxis die hieronder wordt weergegeven.

InlineScript
{
    <Script Block>
} <Common Parameters>

U kunt uitvoer van een InlineScript retourneren door de uitvoer toe te wijzen aan een variabele. In het volgende voorbeeld wordt een service gestopt en wordt vervolgens de servicenaam uitgevoerd.

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

    $Output.Name
}

U kunt waarden doorgeven aan een InlineScript-blok, maar u moet $Using bereikaanpassing gebruiken. Het volgende voorbeeld is identiek aan het vorige voorbeeld, behalve dat de servicenaam wordt opgegeven door een variabele.

Workflow Stop-MyService
{
    $ServiceName = "MyService"

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

    $Output.Name
}

Hoewel InlineScript-activiteiten mogelijk essentieel zijn in bepaalde werkstromen, bieden ze geen ondersteuning voor werkstroomconstructies. Gebruik ze alleen als dat nodig is om de volgende redenen:

  • U kunt geen controlepunten in een InlineScript-blok gebruiken. Als er een fout optreedt in het blok, moet deze worden hervat vanaf het begin van het blok.
  • U kunt parallelle uitvoering niet gebruiken in een InlineScript-blok.
  • InlineScript is van invloed op de schaalbaarheid van de werkstroom omdat deze de Windows PowerShell-sessie bevat voor de volledige lengte van het InlineScript-blok.

Zie Windows PowerShell-opdrachten uitvoeren in een werkstroom en about_InlineScript voor meer informatie over het gebruik van InlineScript.

Parallelle verwerking gebruiken

Een voordeel van Windows PowerShell-werkstromen is de mogelijkheid om een set opdrachten parallel uit te voeren in plaats van sequentieel, net als bij een typisch script.

U kunt het Parallel trefwoord gebruiken om een scriptblok te maken met meerdere opdrachten die gelijktijdig worden uitgevoerd. Hierbij wordt de volgende syntaxis gebruikt die hieronder wordt weergegeven. In dit geval beginnen Activiteit1 en Activiteit2 tegelijkertijd. Activiteit3 wordt pas gestart nadat zowel Activity1 als Activity2 zijn voltooid.

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

Denk bijvoorbeeld aan de volgende PowerShell-opdrachten waarmee meerdere bestanden naar een netwerkbestemming worden gekopieerd. Deze opdrachten worden opeenvolgend uitgevoerd, zodat het kopiëren van het ene bestand moet worden voltooid voordat het volgende wordt gestart.

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

In de volgende werkstroom worden dezelfde opdrachten parallel uitgevoerd, zodat ze allemaal tegelijkertijd kopiëren. Alleen nadat ze allemaal zijn gekopieerd, wordt het voltooiingsbericht weergegeven.

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

U kunt de ForEach -Parallel constructie gebruiken om opdrachten voor elk item in een verzameling gelijktijdig te verwerken. De items in de verzameling worden parallel verwerkt terwijl de opdrachten in het scriptblok opeenvolgend worden uitgevoerd. In dit proces wordt de volgende syntaxis gebruikt die hieronder wordt weergegeven. In dit geval begint Activity1 op hetzelfde moment voor alle items in de verzameling. Voor elk item begint Activity2 nadat Activity1 is voltooid. Activiteit3 wordt pas gestart nadat zowel Activity1 als Activity2 voor alle items zijn voltooid. We gebruiken de ThrottleLimit parameter om de parallelle uitvoering te beperken. Te hoog van een ThrottleLimit kan problemen veroorzaken. De ideale waarde voor de ThrottleLimit parameter is afhankelijk van veel factoren in uw omgeving. Begin met een lage waarde en probeer verschillende toenemende waarden totdat u een waarde vindt die geschikt is voor uw specifieke situatie.

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

Het volgende voorbeeld is vergelijkbaar met het vorige voorbeeld waarin bestanden parallel worden gekopieerd. In dit geval wordt een bericht weergegeven voor elk bestand nadat het is gekopieerd. Pas nadat ze allemaal zijn gekopieerd, wordt het uiteindelijke voltooiingsbericht weergegeven.

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

Notitie

We raden u niet aan onderliggende runbooks parallel uit te voeren, omdat dit is gebleken om onbetrouwbare resultaten te geven. De uitvoer van het onderliggende runbook wordt soms niet weergegeven en instellingen in het ene onderliggende runbook kunnen van invloed zijn op de andere parallelle onderliggende runbooks. Variabelen zoals VerbosePreference, WarningPreferenceen anderen worden mogelijk niet doorgegeven aan de onderliggende runbooks. En als het onderliggende runbook deze waarden wijzigt, worden ze mogelijk niet goed hersteld na aanroep.

Controlepunten gebruiken in een werkstroom

Een controlepunt is een momentopname van de huidige status van de werkstroom met de huidige waarden voor variabelen en uitvoer die op dat punt wordt gegenereerd. Als een werkstroom in een fout eindigt of is onderbroken, begint deze vanaf het laatste controlepunt wanneer deze wordt uitgevoerd, in plaats van aan het begin.

U kunt een controlepunt instellen in een werkstroom met de Checkpoint-Workflow activiteit. Azure Automation heeft een functie genaamd fair share, waarvoor elk runbook dat drie uur wordt uitgevoerd, wordt uitgeladen, zodat andere runbooks kunnen worden uitgevoerd. Uiteindelijk wordt het uitgepakte runbook opnieuw geladen. Wanneer dat het is, wordt de uitvoering hervat vanaf het laatste controlepunt dat in het runbook is genomen.

Om ervoor te zorgen dat het runbook uiteindelijk wordt voltooid, moet u controlepunten toevoegen met intervallen die minder dan drie uur worden uitgevoerd. Als tijdens elke uitvoering een nieuw controlepunt wordt toegevoegd en als het runbook na drie uur wordt verwijderd vanwege een fout, wordt het runbook voor onbepaalde tijd hervat.

In het volgende voorbeeld treedt er een uitzondering op na Activiteit2, waardoor de werkstroom wordt beëindigd. Wanneer de werkstroom opnieuw wordt uitgevoerd, begint deze door Activity2 uit te voeren, omdat deze activiteit net na de laatste controlepuntset was.

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

Stel controlepunten in een werkstroom in na activiteiten die mogelijk gevoelig zijn voor uitzonderingen en mogen niet worden herhaald als de werkstroom wordt hervat. Uw werkstroom kan bijvoorbeeld een virtuele machine maken. U kunt een controlepunt instellen voor en na de opdrachten om de virtuele machine te maken. Als het maken mislukt, worden de opdrachten herhaald als de werkstroom opnieuw wordt gestart. Als de werkstroom mislukt nadat het maken is voltooid, wordt de virtuele machine niet opnieuw gemaakt wanneer de werkstroom wordt hervat.

In het volgende voorbeeld worden meerdere bestanden gekopieerd naar een netwerklocatie en wordt na elk bestand een controlepunt ingesteld. Als de netwerklocatie verloren gaat, eindigt de werkstroom in een fout. Wanneer deze opnieuw wordt gestart, wordt het op het laatste controlepunt hervat. Alleen de bestanden die al zijn gekopieerd, worden overgeslagen.

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

Omdat de referenties van de gebruikersnaam niet worden behouden nadat u de activiteit Werkstroom onderbreken of na het laatste controlepunt hebt aangeroepen, moet u de referenties instellen op null en deze vervolgens opnieuw ophalen uit het assetarchief nadat Suspend-Workflow of het controlepunt is aangeroepen. Anders wordt mogelijk het volgende foutbericht weergegeven: 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.

In dezelfde code ziet u hoe u deze situatie kunt afhandelen in uw 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
        }
}

Notitie

Voor niet-grafische PowerShell-runbooks en Add-AzureRMAccount aliassen Add-AzAccount zijn voor Verbinding maken-AzAccount. U kunt deze cmdlets gebruiken of u kunt uw modules bijwerken naar de nieuwste versie in uw Automation-account. Zelfs wanneer u zojuist een nieuw Automation-account hebt aangemaakt, moet u mogelijk uw modules bijwerken.

Zie Controlepunten toevoegen aan een scriptwerkstroom voor meer informatie over controlepunten.

Volgende stappen