Freigeben über


Definieren der Startreihenfolge für DevTest Lab-VMs mit Azure Automation

In diesem Artikel wird erläutert, wie Sie virtuelle DevTest Labs-Computer (VMs) in einer bestimmten Reihenfolge starten, indem Sie ein PowerShell-Runbook in Azure Automation verwenden. Das PowerShell-Skript verwendet Tags für Lab-VMs, sodass Sie die Startreihenfolge ändern können, ohne das Skript ändern zu müssen.

Mit dem Feature Autostart von DevTest Labs können Sie Lab-VMs so konfigurieren, dass sie zu einer bestimmten Zeit automatisch starten. Manchmal möchten Sie aber vielleicht, dass die Lab-VMs in einer bestimmten Reihenfolge starten. Wenn beispielsweise eine Jumpbox-VM in einem Lab der Zugriffspunkt für die anderen VMs ist, muss die Jumpbox-VM vor den anderen VMs gestartet werden.

Voraussetzungen

  • Erstellen Sie ein Tag namens StartupOrder, und wenden Sie es auf alle Lab-VMs mit einem entsprechenden Startwert von 0 bis 10 an. Kennzeichnen Sie alle Computer, die nicht gestartet werden sollen, mit „-1“.

  • Erstellen Sie ein Azure Automation-Konto. Eine entsprechende Anweisungen finden Sie unter Erstellen eines eigenständigen Azure Automation-Kontos. Wählen Sie beim Erstellen des Kontos die Option Ausführende Konten aus.

Erstellen des PowerShell-Runbooks

  1. Wählen Sie auf der Seite Übersicht für das Automation-Konto im linken Menü die Option Runbooks aus.
  2. Wählen Sie auf der Seite Runbooks die Option Runbook erstellen aus.
  3. Befolgen Sie die Anweisungen unter Erstellen eines Automation PowerShell-Runbooks mithilfe einer verwalteten Identität, um ein PowerShell-Runbook zu erstellen. Füllen Sie das Runbook mit dem folgenden PowerShell-Skript auf.

Vorbereiten des PowerShell-Skripts

Im folgenden Skript werden der Abonnementname und der Lab-Name als Parameter verwendet. Das Skript ruft alle VMs im Lab ab und analysiert deren Tagnamen, um eine Liste der VM-Namen und deren Startreihenfolge zu erstellen. Das Skript geht die Liste der Reihenfolge nach durch und startet die VMs.

Wenn mehrere VMs in einer bestimmten Reihenfolge vorhanden sind, werden diese VMs über PowerShell-Aufträge asynchron gestartet. Für virtuelle Computer ohne Tag wird der Startwert auf 10 festgelegt und sie starten standardmäßig als letztes. Das Skript ignoriert alle virtuellen Computer, die andere Tagwerte als 0 bis 10 aufweisen.

#Requires -Version 3.0
#Requires -Module AzureRM.Resources

param
(
    [Parameter(Mandatory=$false, HelpMessage="Name of the subscription that has the lab")]
    [string] $SubscriptionName,

    [Parameter(Mandatory=$false, HelpMessage="Lab name")]
    [string] $LabName
)

# Connect and add the appropriate subscription
$Conn = Get-AutomationConnection -Name AzureRunAsConnection

Add-AzureRMAccount -ServicePrincipal -Tenant $Conn.TenantID -ApplicationID $Conn.ApplicationId -Subscription $SubscriptionName -CertificateThumbprint $Conn.CertificateThumbprint

# Find the lab
$dtLab = Find-AzResource -ResourceType 'Microsoft.DevTestLab/labs' -ResourceNameEquals $LabName

# Get the VMs
$dtlAllVms = New-Object System.Collections.ArrayList
$AllVMs = Get-AzResource -ResourceId "$($dtLab.ResourceId)/virtualmachines" -ApiVersion 2016-05-15

# Get the StartupOrder tag. If missing, set to start up last (10).
ForEach ($vm in $AllVMs) {
    if ($vm.Tags) {
        if ($vm.Tags['StartupOrder']) {
            $startupValue = $vm.Tags['StartupOrder']
        } else {
            $startupValue = 10
        }
        } else {
            $startupValue = 10
        }
        $dtlAllVms.Add(@{$vm.Name = $startupValue}) > $null
}

# Setup for the async multiple vm start

# Save profile
$profilePath = Join-Path $env:Temp "profile.json"
If (Test-Path $profilePath){
    Remove-Item $profilePath
}
Save-AzContext -Path $profilePath

# Job to start VMs asynch
$startVMBlock = {
    Param($devTestLab,$vmToStart,$profilePath)
    Import-AzContext -Path ($profilePath)
    Invoke-AzResourceAction `
        -ResourceId "$($devTestLab.ResourceId)/virtualmachines/$vmToStart" `
        -Action Start `
        -Force
    Write-Output "Started: $vmToStart"
}

$current = 0
# Start in order from 0 to 10

While ($current -le 10) {
# Get the VMs in the current stage
    $tobeStarted = $null
    $tobeStarted = $dtlAllVms | Where-Object { $_.Values -eq $current}
    if ($tobeStarted.Count -eq 1) {
        # Run sync – jobs not necessary for a single VM
        $returnStatus = Invoke-AzResourceAction `
                -ResourceId "$($dtLab.ResourceId)/virtualmachines/$($tobeStarted.Keys)" `
                -Action Start `
                -Force
        Write-Output "$($tobeStarted.Keys) status: $($returnStatus.status)"
    } elseif ($tobeStarted.Count -gt 1) {
        # Start multiple VMs async
        $jobs = @()
        Write-Output "Start Jobs start: $(Get-Date)"
        
        # Jobs
        $jobs += Start-Job -ScriptBlock $startVMBlock -ArgumentList $dtLab, $($singlevm.Keys), $profilePath
        Write-Output "Start Jobs end: $(Get-Date)"
    }

    # Get results from all jobs
    if($jobs.Count -ne 0) {
        Write-Output "Receive Jobs start: $(Get-Date)"
        foreach ($job in $jobs){
            $jobResult = Receive-Job -Job $job -Wait | Write-Output
        }
        Remove-Job -Job $jobs -Force
    }
    else
    {
        Write-Output "Information: No jobs available"
    }
}

Ausführen des Skripts

  • Um dieses Skript täglich auszuführen, erstellen Sie einen Zeitplan im Automation-Konto, und verknüpfen Sie den Zeitplan mit dem Runbook.

  • In einem Unternehmensszenario mit mehreren Abonnements, die mehrere Labs enthalten, können Sie die Parameterinformationen für verschiedene Labs und Abonnements in einer Datei speichern. Übergeben Sie dann anstelle der einzelnen Parameter diese Datei an das Skript.

  • In diesem Beispiel wird Azure Automation zum Ausführen des PowerShell-Skripts verwendet. Sie können aber auch andere Optionen verwenden, z. B. eine Build-/Releasepipeline.

Nächste Schritte