Lär dig PowerShell-arbetsflöde för Azure Automation

Runbooks i Azure Automation implementeras som Windows PowerShell-arbetsflöden, Windows PowerShell-skript som använder Windows Workflow Foundation. Ett arbetsflöde är en sekvens med programmerade, nätverksanslutna steg som utför tidskrävande uppgifter eller kräver samordning av flera steg i flera enheter eller hanterade noder.

Ett arbetsflöde skrivs med Windows PowerShell-syntax och startas av Windows PowerShell, men bearbetas av Windows Workflow Foundation. Fördelarna med ett arbetsflöde jämfört med ett normalt skript är samtidiga prestanda för en åtgärd mot flera enheter och automatisk återställning från fel.

Kommentar

Den här artikeln gäller för PowerShell 5.1. PowerShell 7.1 (förhandsversion) och PowerShell 7.2 (förhandsversion) stöder inte arbetsflöden. Ett PowerShell-arbetsflödesskript liknar ett Windows PowerShell-skript men har vissa betydande skillnader som kan vara förvirrande för en ny användare. Därför rekommenderar vi att du skriver dina runbooks med PowerShell-arbetsflöde endast om du behöver använda kontrollpunkter.

Fullständig information om ämnena i den här artikeln finns i Komma igång med Windows PowerShell-arbetsflöde.

Använda nyckelordet Arbetsflöde

Det första steget för att konvertera ett PowerShell-skript till ett PowerShell-arbetsflöde är att omsluta det med nyckelordet Workflow . Ett arbetsflöde börjar med nyckelordet Workflow följt av brödtexten i skriptet som omges av klammerparenteser. Namnet på arbetsflödet följer nyckelordet Workflow enligt följande syntax:

Workflow Test-Workflow
{
    <Commands>
}

Namnet på arbetsflödet måste matcha namnet på Automation-runbooken. Om runbooken importeras måste filnamnet matcha arbetsflödets namn och sluta med .ps1.

Om du vill lägga till parametrar i arbetsflödet använder du nyckelordet Param precis som i ett skript.

Lär dig skillnader mellan PowerShell-arbetsflödeskod och PowerShell-skriptkod

PowerShell-arbetsflödeskoden ser nästan identisk ut med PowerShell-skriptkoden förutom några betydande ändringar. I följande avsnitt beskrivs ändringar som du behöver göra i ett PowerShell-skript för att det ska kunna köras i ett arbetsflöde.

Aktiviteter

En aktivitet är en specifik uppgift i ett arbetsflöde som utförs i en sekvens. Windows PowerShell-arbetsflödet konverterar automatiskt många av Windows PowerShell-cmdletarna till aktiviteter när det kör ett arbetsflöde. När du anger någon av dessa cmdletar i din runbook körs motsvarande aktivitet av Windows Workflow Foundation.

Om en cmdlet inte har någon motsvarande aktivitet kör Windows PowerShell Workflow automatiskt cmdleten i en InlineScript-aktivitet . Vissa cmdletar undantas och kan inte användas i ett arbetsflöde om du inte uttryckligen inkluderar dem i ett InlineScript-block. Mer information finns i Använda aktiviteter i skriptarbetsflöden.

Arbetsflödesaktiviteter delar en uppsättning vanliga parametrar för att konfigurera åtgärden. Se about_WorkflowCommonParameters.

Positionsparametrar

Du kan inte använda positionsparametrar med aktiviteter och cmdletar i ett arbetsflöde. Därför måste du använda parameternamn. Tänk på följande kod som hämtar alla tjänster som körs:

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

Om du försöker köra den här koden i ett arbetsflöde får du ett meddelande som Parameter set cannot be resolved using the specified named parameters. Till rätta för det här problemet, ange parameternamnet, som i följande exempel:

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

Deserialiserade objekt

Objekt i arbetsflöden deserialiseras, vilket innebär att deras egenskaper fortfarande är tillgängliga, men inte deras metoder. Tänk till exempel på följande PowerShell-kod, som stoppar en tjänst med Stop hjälp av -metoden för Service objektet.

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

Om du försöker köra detta i ett arbetsflöde får du ett felmeddelande om att Method invocation is not supported in a Windows PowerShell Workflow.

Ett alternativ är att omsluta dessa två kodrader i ett InlineScript-block . I det här fallet Service representerar ett tjänstobjekt i blocket.

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

Ett annat alternativ är att använda en annan cmdlet som har samma funktioner som metoden, om en är tillgänglig. I vårt exempel Stop-Service innehåller cmdleten samma funktioner som Stop metoden, och du kan använda följande kod för ett arbetsflöde.

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

Använda InlineScript

AktivitetenInlineScript är användbar när du behöver köra ett eller flera kommandon som traditionellt PowerShell-skript i stället för PowerShell-arbetsflöde. Kommandon i ett arbetsflöde skickas till Windows Workflow Foundation för bearbetning, men kommandon i ett InlineScript-block bearbetas av Windows PowerShell.

InlineScript använder följande syntax som visas nedan.

InlineScript
{
    <Script Block>
} <Common Parameters>

Du kan returnera utdata från en InlineScript genom att tilldela utdata till en variabel. I följande exempel stoppas en tjänst och tjänstnamnet matas sedan ut.

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

    $Output.Name
}

Du kan skicka värden till ett InlineScript-block, men du måste använda $Using omfångsmodifierare. Följande exempel är identiskt med föregående exempel förutom att tjänstnamnet tillhandahålls av en variabel.

Workflow Stop-MyService
{
    $ServiceName = "MyService"

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

    $Output.Name
}

InlineScript-aktiviteter kan vara viktiga i vissa arbetsflöden, men de stöder inte arbetsflödeskonstruktioner. Du bör endast använda dem när det behövs av följande skäl:

  • Du kan inte använda kontrollpunkter i ett InlineScript-block. Om ett fel inträffar i blocket måste det återupptas från början av blocket.
  • Du kan inte använda parallell körning i ett InlineScript-block.
  • InlineScript påverkar arbetsflödets skalbarhet eftersom det innehåller Windows PowerShell-sessionen under hela inlineScript-blocket.

Mer information om hur du använder InlineScript finns i Köra Windows PowerShell-kommandon i ett arbetsflöde och about_InlineScript.

Använda parallell bearbetning

En fördel med Windows PowerShell-arbetsflöden är möjligheten att utföra en uppsättning kommandon parallellt i stället för sekventiellt som med ett typiskt skript.

Du kan använda nyckelordet Parallel för att skapa ett skriptblock med flera kommandon som körs samtidigt. Detta använder följande syntax som visas nedan. I det här fallet startar Activity1 och Activity2 samtidigt. Activity3 startar först efter att både Activity1 och Activity2 har slutförts.

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

Tänk dig till exempel följande PowerShell-kommandon som kopierar flera filer till ett nätverksmål. Dessa kommandon körs sekventiellt så att en fil måste slutföra kopieringen innan nästa startas.

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

Följande arbetsflöde kör samma kommandon parallellt så att alla börjar kopiera samtidigt. Först när alla har kopierats visas slutförandemeddelandet.

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

Du kan använda konstruktionen ForEach -Parallel för att bearbeta kommandon för varje objekt i en samling samtidigt. Objekten i samlingen bearbetas parallellt medan kommandona i skriptblocket körs sekventiellt. Den här processen använder följande syntax som visas nedan. I det här fallet startar Activity1 samtidigt för alla objekt i samlingen. För varje objekt startar Activity2 när Activity1 har slutförts. Activity3 startar endast efter att både Activity1 och Activity2 har slutförts för alla objekt. Vi använder parametern ThrottleLimit för att begränsa parallelliteten. För hög av en ThrottleLimit kan orsaka problem. Det ideala värdet för parametern ThrottleLimit beror på många faktorer i din miljö. Börja med ett lågt värde och prova olika ökande värden tills du hittar ett som fungerar för din specifika situation.

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

Följande exempel liknar det tidigare exemplet som kopierar filer parallellt. I det här fallet visas ett meddelande för varje fil när den har kopierats. Först när alla har kopierats visas det slutliga slutförandemeddelandet.

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

Kommentar

Vi rekommenderar inte att du kör underordnade runbooks parallellt eftersom detta har visat sig ge otillförlitliga resultat. Utdata från den underordnade runbooken visas ibland inte, och inställningar i en underordnad runbook kan påverka de andra parallella underordnade runbooksna. Variabler som VerbosePreference, WarningPreferenceoch andra kanske inte sprids till underordnade runbooks. Och om den underordnade runbooken ändrar dessa värden kanske de inte återställs korrekt efter anropet.

Använda kontrollpunkter i ett arbetsflöde

En kontrollpunkt är en ögonblicksbild av arbetsflödets aktuella tillstånd som innehåller aktuella värden för variabler och eventuella utdata som genereras till den punkten. Om ett arbetsflöde slutar med ett fel eller pausas startar det från den sista kontrollpunkten nästa gång det körs, i stället för att starta i början.

Du kan ange en kontrollpunkt i ett arbetsflöde med Checkpoint-Workflow aktiviteten. Azure Automation har en funktion som kallas rättvis resurs, för vilken alla runbooks som körs i tre timmar tas bort så att andra runbooks kan köras. Så småningom laddas den borttagna runbooken om. När det är det återupptas körningen från den senaste kontrollpunkten som togs i runbooken.

För att garantera att runbooken slutförs så småningom måste du lägga till kontrollpunkter med intervall som körs i mindre än tre timmar. Om en ny kontrollpunkt läggs till under varje körning och runbooken tas bort efter tre timmar på grund av ett fel återupptas runbooken på obestämd tid.

I följande exempel inträffar ett undantag efter Activity2, vilket gör att arbetsflödet slutar. När arbetsflödet körs igen börjar det med att köra Activity2, eftersom den här aktiviteten var strax efter den senaste kontrollpunktsuppsättningen.

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

Ange kontrollpunkter i ett arbetsflöde efter aktiviteter som kan vara undantagsbenägna och bör inte upprepas om arbetsflödet återupptas. Ditt arbetsflöde kan till exempel skapa en virtuell dator. Du kan ange en kontrollpunkt både före och efter kommandona för att skapa den virtuella datorn. Om skapandet misslyckas upprepas kommandona om arbetsflödet startas igen. Om arbetsflödet misslyckas när det har skapats skapas inte den virtuella datorn igen när arbetsflödet återupptas.

I följande exempel kopieras flera filer till en nätverksplats och en kontrollpunkt anges efter varje fil. Om nätverksplatsen går förlorad slutar arbetsflödet i fel. När den startas igen återupptas den vid den senaste kontrollpunkten. Endast de filer som redan har kopierats hoppas över.

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

Eftersom autentiseringsuppgifterna för användarnamn inte sparas efter att du har anropat aktiviteten Pausa arbetsflödet eller efter den senaste kontrollpunkten måste du ange autentiseringsuppgifterna till null och sedan hämta dem igen från tillgångsarkivet efter Suspend-Workflow att eller kontrollpunkten anropats. Annars kan du få följande felmeddelande: 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.

Följande kod visar hur du hanterar den här situationen i dina 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
        }
}

Kommentar

För icke-grafiska PowerShell-runbooks Add-AzAccount och Add-AzureRMAccount är alias för Anslut-AzAccount. Du kan använda dessa cmdletar eller uppdatera dina moduler i ditt Automation-konto till de senaste versionerna. Du kan behöva uppdatera dina moduler även om du just har skapat ett nytt Automation-konto.

Mer information om kontrollpunkter finns i Lägga till kontrollpunkter i ett skriptarbetsflöde.

Nästa steg