Condividi tramite


Definire l'ordine di avvio per le macchine virtuali DevTest Lab con Automazione di Azure

Questo articolo illustra come avviare le macchine virtuali di DevTest Labs in un ordine specifico usando un runbook di PowerShell in Automazione di Azure. Lo script di PowerShell usa tag nelle macchine virtuali del lab, quindi è possibile modificare l'ordine di avvio senza dover modificare lo script.

La funzionalità di avvio automatico di DevTest Labs può configurare le macchine virtuali del lab per l'avvio automatico in un determinato momento. Tuttavia, a volte è possibile che le macchine virtuali del lab vengano avviate in una sequenza specifica. Ad esempio, se una macchina virtuale jumpbox in un lab è il punto di accesso alle altre macchine virtuali, la macchina virtuale jumpbox deve essere avviata prima delle altre macchine virtuali.

Prerequisiti

  • Creare e applicare un tag denominato StartupOrder a tutte le macchine virtuali del lab con un valore di avvio appropriato, da 0 a 10. Designare tutti i computer che non richiedono l'avvio come -1.

  • Creare un account Automazione di Azure seguendo le istruzioni riportate in Creare un account Automazione di Azure autonomo. Scegliere l'opzione Account RunAs quando si crea l'account.

Creare il runbook di PowerShell

  1. Nella pagina Panoramica per l'account di Automazione selezionare Runbook dal menu a sinistra.
  2. Nella pagina Runbook selezionare Crea un runbook.
  3. Seguire le istruzioni in Creare un runbook di PowerShell di Automazione usando l'identità gestita per creare un runbook di PowerShell. Popolare il runbook con lo script di PowerShell seguente.

Preparare lo script di PowerShell

Lo script seguente accetta il nome della sottoscrizione e il nome del lab come parametri. Lo script ottiene tutte le macchine virtuali nel lab e analizza le informazioni sui tag per creare un elenco di nomi di vm e il relativo ordine di avvio. Lo script illustra l'elenco in ordine e avvia le macchine virtuali.

Se sono presenti più macchine virtuali in un numero di ordine specifico, tali macchine virtuali vengono avviate in modo asincrono usando i processi di PowerShell. Le macchine virtuali che non hanno un tag hanno il valore di avvio impostato su 10 e iniziano per ultimo per impostazione predefinita. Lo script ignora tutte le macchine virtuali con valori di tag diversi da 0 a 10.

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

Eseguire lo script

  • Per eseguire questo script ogni giorno, creare una pianificazione nell'account di Automazione e collegare la pianificazione al runbook.

  • In uno scenario aziendale con più sottoscrizioni con più lab, è possibile archiviare le informazioni sui parametri per lab e sottoscrizioni diversi in un file. Passare il file allo script anziché passare i singoli parametri.

  • Questo esempio usa Automazione di Azure per eseguire lo script di PowerShell, ma è anche possibile usare altre opzioni, ad esempio una pipeline di compilazione/versione.

Passaggi successivi