Poznaj przepływ pracy programu PowerShell dla usługi Azure Automation

Elementy Runbook w usłudze Azure Automation są implementowane jako przepływy pracy programu Windows PowerShell, skrypty programu Windows PowerShell korzystające z programu Windows Workflow Foundation. Przepływ pracy to sekwencja zaprogramowanych, połączonych ze sobą czynności służących do wykonywania długotrwałych zadań lub do zapewnienia koordynacji wielu czynności na wielu różnych urządzeniach albo w wielu węzłach zarządzanych.

Podczas gdy przepływ pracy jest napisany przy użyciu składni programu Windows PowerShell i uruchamiany przez program Windows PowerShell, jest przetwarzany przez program Windows Workflow Foundation. Zalety przepływu pracy za pośrednictwem normalnego skryptu obejmują równoczesną wydajność akcji względem wielu urządzeń i automatyczne odzyskiwanie po awariach.

Uwaga

Ten artykuł dotyczy programu PowerShell 5.1; Program PowerShell 7.1 (wersja zapoznawcza) i program PowerShell 7.2 (wersja zapoznawcza) nie obsługuje przepływów pracy. Skrypt przepływu pracy programu PowerShell jest bardzo podobny do skryptu programu Windows PowerShell, ale ma pewne istotne różnice, które mogą być mylące dla nowego użytkownika. W związku z tym zalecamy pisanie elementów Runbook przy użyciu przepływu pracy programu PowerShell tylko wtedy, gdy trzeba używać punktów kontrolnych.

Aby uzyskać szczegółowe informacje na temat tematów w tym artykule, zobacz Wprowadzenie do przepływu pracy programu Windows PowerShell.

Użyj słowa kluczowego Przepływ pracy

Pierwszym krokiem konwertowania skryptu programu PowerShell na przepływ pracy programu PowerShell jest ujęcie go w Workflow słowo kluczowe . Przepływ pracy rozpoczyna się od Workflow słowa kluczowego, po którym następuje treść skryptu ujętego w nawiasy klamrowe. Nazwa przepływu pracy jest zgodna ze Workflow słowem kluczowym, jak pokazano w następującej składni:

Workflow Test-Workflow
{
    <Commands>
}

Nazwa przepływu pracy musi być zgodna z nazwą elementu Runbook usługi Automation. Jeśli element Runbook jest importowany, nazwa pliku musi być zgodna z nazwą przepływu pracy i musi kończyć się ciągiem .ps1.

Aby dodać parametry do przepływu pracy, użyj Param słowa kluczowego tak samo jak w skrycie.

Poznaj różnice między kodem przepływu pracy programu PowerShell i kodem skryptu programu PowerShell

Kod przepływu pracy programu PowerShell wygląda prawie identycznie z kodem skryptu programu PowerShell, z wyjątkiem kilku znaczących zmian. W poniższych sekcjach opisano zmiany, które należy wprowadzić do skryptu programu PowerShell, aby był uruchamiany w przepływie pracy.

Działania

Działanie jest określonym zadaniem w przepływie pracy wykonywanym w sekwencji. Przepływ pracy programu Windows PowerShell automatycznie konwertuje wiele poleceń cmdlet programu Windows PowerShell na działania uruchamiane przez przepływ pracy. Po określeniu jednego z tych poleceń cmdlet w elememencie Runbook odpowiednie działanie jest uruchamiane przez program Windows Workflow Foundation.

Jeśli polecenie cmdlet nie ma odpowiedniego działania, przepływ pracy programu Windows PowerShell automatycznie uruchamia polecenie cmdlet w działaniu inlineScript . Niektóre polecenia cmdlet są wykluczone i nie można ich używać w przepływie pracy, chyba że jawnie dołączysz je do bloku wbudowanego koduScript. Aby uzyskać więcej informacji, zobacz Using Activities in Script Workflows (Używanie działań w przepływach pracy skryptów).

Działania przepływu pracy współużytkują zestaw typowych parametrów, aby skonfigurować operację. Zobacz about_WorkflowCommonParameters.

Parametry pozycyjne

Nie można używać parametrów pozycyjnych z działaniami i poleceniami cmdlet w przepływie pracy. W związku z tym należy użyć nazw parametrów. Rozważ następujący kod, który pobiera wszystkie uruchomione usługi:

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

Jeśli spróbujesz uruchomić ten kod w przepływie pracy, zostanie wyświetlony komunikat podobny Parameter set cannot be resolved using the specified named parameters. Do rozwiązania tego problemu, podaj nazwę parametru, jak w poniższym przykładzie:

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

Deserializowane obiekty

Obiekty w przepływach pracy są deserializowane, co oznacza, że ich właściwości są nadal dostępne, ale nie ich metody. Rozważmy na przykład następujący kod programu PowerShell, który zatrzymuje usługę przy użyciu Stop metody Service obiektu.

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

Jeśli spróbujesz uruchomić to w przepływie pracy, zostanie wyświetlony komunikat o błędzie informujący o błędzie Method invocation is not supported in a Windows PowerShell Workflow.

Jedną z opcji jest opakowywanie tych dwóch wierszy kodu w bloku śródliniowym. W tym przypadku Service reprezentuje obiekt usługi w bloku.

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

Inną opcją jest użycie innego polecenia cmdlet, które ma taką samą funkcjonalność jak metoda, jeśli jest dostępna. W naszym przykładzie Stop-Service polecenie cmdlet zapewnia taką samą funkcjonalność jak Stop metoda i można użyć następującego kodu dla przepływu pracy.

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

Korzystanie z wbudowanego koduScript

DziałanieInlineScript jest przydatne, gdy musisz uruchomić co najmniej jedno polecenie jako tradycyjny skrypt programu PowerShell zamiast przepływu pracy programu PowerShell. Podczas gdy polecenia w przepływie pracy są wysyłane do programu Windows Workflow Foundation do przetwarzania, polecenia w bloku śródliniowym językaScript są przetwarzane przez program Windows PowerShell.

Język InlineScript używa poniższej składni.

InlineScript
{
    <Script Block>
} <Common Parameters>

Dane wyjściowe można zwrócić z inlineScript, przypisując dane wyjściowe do zmiennej. Poniższy przykład zatrzymuje usługę, a następnie generuje nazwę usługi.

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

    $Output.Name
}

Wartości można przekazać do bloku InlineScript, ale należy użyć modyfikatora zakresu $Using . Poniższy przykład jest identyczny z poprzednim przykładem, z tą różnicą, że nazwa usługi jest dostarczana przez zmienną.

Workflow Stop-MyService
{
    $ServiceName = "MyService"

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

    $Output.Name
}

Chociaż działania w tekścieScript mogą mieć krytyczne znaczenie w niektórych przepływach pracy, nie obsługują konstrukcji przepływu pracy. Należy ich używać tylko wtedy, gdy jest to konieczne z następujących powodów:

  • Nie można używać punktów kontrolnych wewnątrz bloku ŚródlineScript. Jeśli w bloku wystąpi błąd, musi zostać wznowione od początku bloku.
  • Nie można używać wykonywania równoległego wewnątrz bloku InlineScript.
  • Język InlineScript ma wpływ na skalowalność przepływu pracy, ponieważ przechowuje sesję programu Windows PowerShell dla całej długości bloku InlineScript.

Aby uzyskać więcej informacji na temat korzystania z języka InlineScript, zobacz Running Windows PowerShell Commands in a Workflow and about_InlineScript (Uruchamianie poleceń programu Windows PowerShell w przepływie pracy i about_InlineScript).

Korzystanie z przetwarzania równoległego

Jedną z zalet przepływów pracy programu Windows PowerShell jest możliwość równoległego wykonywania zestawu poleceń zamiast sekwencyjnie, jak w przypadku typowego skryptu.

Możesz użyć słowa kluczowego Parallel , aby utworzyć blok skryptu z wieloma poleceniami uruchamianymi jednocześnie. W tym celu użyto następującej składni pokazanej poniżej. W takim przypadku działania Activity1 i Activity2 są uruchamiane w tym samym czasie. Działanie 3 rozpoczyna się dopiero po zakończeniu działania Activity1 i Activity2.

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

Rozważmy na przykład następujące polecenia programu PowerShell, które kopiują wiele plików do miejsca docelowego sieci. Te polecenia są uruchamiane sekwencyjnie, aby jeden plik musiał zakończyć kopiowanie przed rozpoczęciem następnego.

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

Poniższy przepływ pracy uruchamia te same polecenia równolegle, aby wszystkie uruchamiały kopiowanie w tym samym czasie. Wyświetlany jest komunikat ukończenia dopiero po ich skopiowaniu.

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

Konstrukcji można używać do przetwarzania ForEach -Parallel poleceń dla każdego elementu w kolekcji jednocześnie. Elementy w kolekcji są przetwarzane równolegle, podczas gdy polecenia w bloku skryptu są uruchamiane sekwencyjnie. W tym procesie jest używana następująca składnia pokazana poniżej. W takim przypadku działanie Activity1 rozpoczyna się jednocześnie dla wszystkich elementów w kolekcji. Dla każdego elementu działanie Activity2 rozpoczyna się po zakończeniu działania Activity1. Działanie 3 rozpoczyna się dopiero po zakończeniu działania Activity1 i Activity2 dla wszystkich elementów. Używamy parametru ThrottleLimit , aby ograniczyć równoległość. Zbyt wysoka wartość ThrottleLimit może powodować problemy. Idealna wartość parametru ThrottleLimit zależy od wielu czynników w danym środowisku. Zacznij od niskiej wartości i spróbuj użyć różnych wartości rosnących, dopóki nie znajdziesz wartości, która działa dla konkretnych okoliczności.

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

Poniższy przykład jest podobny do poprzedniego przykładowego kopiowania plików równolegle. W takim przypadku jest wyświetlany komunikat dla każdego pliku po jego skopiowaniu. Dopiero po skopiowaniu wszystkich kopiowanych jest wyświetlany końcowy komunikat ukończenia.

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

Uwaga

Nie zalecamy równoległego uruchamiania podrzędnych elementów Runbook, ponieważ pokazano, że daje to niewiarygodne wyniki. Dane wyjściowe podrzędnego elementu Runbook czasami nie są wyświetlane, a ustawienia w jednym podrzędnym elemecie Runbook mogą mieć wpływ na inne równoległe podrzędne elementy Runbook. Zmienne, takie jak VerbosePreference, WarningPreferencei inne, mogą nie być propagowane do podrzędnych elementów Runbook. A jeśli podrzędny element Runbook zmieni te wartości, może nie zostać prawidłowo przywrócony po wywołaniu.

Używanie punktów kontrolnych w przepływie pracy

Punkt kontrolny to migawka bieżącego stanu przepływu pracy, która zawiera bieżące wartości zmiennych i wszystkie dane wyjściowe wygenerowane w tym punkcie. Jeśli przepływ pracy kończy się błędem lub jest zawieszony, rozpoczyna się od ostatniego punktu kontrolnego przy następnym uruchomieniu, zamiast rozpoczynać się od początku.

Punkt kontrolny można ustawić w przepływie pracy za Checkpoint-Workflow pomocą działania. Usługa Azure Automation ma funkcję o nazwie fair share, dla której każdy element Runbook uruchamiany przez trzy godziny jest zwalniany, aby umożliwić uruchamianie innych elementów Runbook. Ostatecznie zwolniony element Runbook zostanie ponownie załadowany. Gdy jest, wznawia wykonywanie z ostatniego punktu kontrolnego podjętego w elemecie Runbook.

Aby zagwarantować, że element Runbook zostanie ostatecznie ukończony, należy dodać punkty kontrolne w odstępach czasu, które są uruchamiane przez mniej niż trzy godziny. Jeśli podczas każdego przebiegu zostanie dodany nowy punkt kontrolny, a element Runbook zostanie wykluczony po trzech godzinach z powodu błędu, element Runbook zostanie wznowiony w nieskończoność.

W poniższym przykładzie wyjątek występuje po działaniu Activity2, co powoduje zakończenie przepływu pracy. Po ponownym uruchomieniu przepływu pracy rozpoczyna się od uruchomienia działania Activity2, ponieważ to działanie było tuż po ostatnim zestawie punktów kontrolnych.

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

Ustaw punkty kontrolne w przepływie pracy po działaniach, które mogą być podatne na wyjątki i nie powinny być powtarzane, jeśli przepływ pracy zostanie wznowiony. Na przykład przepływ pracy może utworzyć maszynę wirtualną. Punkt kontrolny można ustawić zarówno przed, jak i po poleceniach, aby utworzyć maszynę wirtualną. Jeśli tworzenie zakończy się niepowodzeniem, polecenia będą powtarzane, jeśli przepływ pracy zostanie uruchomiony ponownie. Jeśli przepływ pracy zakończy się niepowodzeniem po pomyślnym utworzeniu, maszyna wirtualna nie zostanie ponownie utworzona po wznowieniu przepływu pracy.

Poniższy przykład kopiuje wiele plików do lokalizacji sieciowej i ustawia punkt kontrolny po każdym pliku. Jeśli lokalizacja sieciowa zostanie utracona, przepływ pracy kończy się błędem. Po ponownym uruchomieniu zostanie wznowiony w ostatnim punkcie kontrolnym. Pomijane są tylko pliki, które zostały już skopiowane.

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

Ponieważ poświadczenia nazwy użytkownika nie są utrwalane po wywołaniu działania Suspend-Workflow lub po ostatnim punkcie kontrolnym, należy ustawić poświadczenia na null, a następnie pobrać je ponownie z magazynu zasobów po Suspend-Workflow wywołaniu lub punktu kontrolnego. W przeciwnym razie może zostać wyświetlony następujący komunikat o błędzie: 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.

Poniższy kod pokazuje, jak obsługiwać tę sytuację w elementach Runbook przepływu pracy programu 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
        }
}

Uwaga

W przypadku niegraficznych elementów Runbook Add-AzAccount programu PowerShell i Add-AzureRMAccount są aliasami dla Połączenie-AzAccount. Możesz użyć tych poleceń cmdlet lub zaktualizować moduły na koncie usługi Automation do najnowszych wersji. Może być konieczne zaktualizowanie modułów, nawet jeśli właśnie utworzono nowe konto usługi Automation.

Aby uzyskać więcej informacji na temat punktów kontrolnych, zobacz Dodawanie punktów kontrolnych do przepływu pracy skryptu.

Następne kroki