Compartilhar via


Definir a ordem de inicialização para VMs do DevTest Lab com Automação do Azure

Este artigo explica como iniciar VMs (máquinas virtuais) do DevTest Labs em uma ordem específica usando um runbook do PowerShell Automação do Azure. O script do PowerShell usa marcas em VMs no laboratório para você controlar a ordem de inicialização sem alterar o script.

O recurso de inicialização automática do DevTest Labs permite configurar VMs para iniciar automaticamente em um horário especificado. No entanto, às vezes você pode querer que as VMs de laboratório iniciem em uma sequência específica. Por exemplo, se uma VM jumpbox em um laboratório for o ponto de acesso para as outras VMs, a VM jumpbox deverá iniciar antes das outras VMs.

Pré-requisitos

Criar o runbook do PowerShell

  1. Na página Visão geral da Conta de Automação, selecione Runbooks no menu à esquerda.
  2. Na página Runbooks, selecione Adicionar um runbook.
  3. Siga as instruções em Criar um runbook do PowerShell de Automação usando a identidade gerenciada para criar um runbook do PowerShell. Preencha o runbook com o script do PowerShell a seguir.

Preparar o script do PowerShell

O script a seguir usa o nome da assinatura e o nome do laboratório como parâmetros. O script obtém todas as VMs no laboratório e analisa as informações de marca para criar uma lista de nomes de VM e a ordem de inicialização delas. O script analisa a lista e inicia as VMs na ordem.

Se houver várias VMs em um número de ordem específico, elas iniciam de maneira assíncrona usando trabalhos do PowerShell. As VMs que não têm uma marca têm seu valor de inicialização definido como 10 e começam por último por padrão. O script ignora todas as VMs que têm valores de marca diferentes de 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"
    }
}

Executar o script

  • Para executar esse script diariamente, crie uma agenda na Conta de Automação e vincule a agenda ao runbook.

  • Em um cenário empresarial que tem várias assinaturas com vários laboratórios, você pode armazenar as informações de parâmetro para diferentes laboratórios e assinaturas em um arquivo. Passe o arquivo para o script em vez de passar os parâmetros individuais.

  • Este exemplo usa Automação do Azure para executar o script do PowerShell, mas você também pode usar outras opções, como um pipeline de build/lançamento.

Próximas etapas