Compartir a través de


Definición del orden de inicio de máquinas virtuales de DevTest Labs con Azure Automation

En este artículo se detalla cómo iniciar máquinas virtuales (VM) de DevTest Labs en un orden específico mediante el uso de un runbook de PowerShell en Azure Automation. El script de PowerShell utiliza etiquetas en las máquinas virtuales del laboratorio para permitirle controlar el orden de inicio sin tener que cambiar el script.

La característica de inicio automático de DevTest Labs le permite configurar el inicio automático de las máquinas virtuales a una hora determinada. Sin embargo, a veces es posible que quiera que las máquinas virtuales del laboratorio se inicien en una secuencia específica. Por ejemplo, si la máquina virtual jumpbox de un laboratorio es el punto de acceso a las otras máquinas virtuales, esta deberá iniciarse antes que las demás.

Requisitos previos

Creación del runbook de PowerShell

  1. En la página Información general de la cuenta de Automation, seleccione Runbooks en el menú izquierdo.
  2. En la página Runbooks seleccione Crear un Runbook.
  3. Siga las instrucciones que se detallan en el artículo Tutorial: Creación de un runbook de PowerShell de Automation mediante una identidad administrada para crear un runbook de PowerShell. Rellene el runbook con el siguiente script de PowerShell.

Preparación del script de PowerShell

El siguiente script utiliza los nombres de la suscripción y el laboratorio como parámetros. El script detectará todas las máquinas virtuales del laboratorio y analizará la información de sus etiquetas para crear una lista de los nombres de las máquinas y su orden de inicio. El script recorrerá e iniciará las máquinas virtuales en orden de lista.

Si varias máquinas virtuales comparten un número de orden específico, estas se iniciarán de forma asincrónica mediante trabajos de PowerShell. El valor de inicio de las máquinas virtuales que no tengan una etiqueta se establecerá en 10 y, de forma predeterminada, estas serán las últimas en iniciarse. El script omitirá las máquinas virtuales que tengan valores de etiqueta que no vayan del 0 al 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"
    }
}

Ejecute el script.

  • Para ejecutar este script diariamente, cree una programación en la cuenta de Automation y vincúlela con el runbook.

  • En un escenario empresarial con varias suscripciones y laboratorios, podrá utilizar un archivo para almacenar la información de los parámetros de los diferentes laboratorios y suscripciones. Pase el archivo al script en lugar de pasar los parámetros individuales.

  • Aunque en este ejemplo se muestra cómo Azure Automation ejecuta el script de PowerShell, también puede usar otras opciones, como una canalización de versión o compilación.

Pasos siguientes