共用方式為


使用 Azure 自動化定義 DevTest Lab VM 的啟動順序

本文說明如何使用 Azure 自動化中的 PowerShell Runbook,以特定順序啟動 DevTest Labs 虛擬機器 (VM)。 PowerShell 指令碼會使用實驗室 VM 上的標籤,因此您可以變更啟動順序,而不需要變更指令碼。

DevTest Labs 自動啟動功能可以設定實驗室 VM,以在指定的時間自動啟動。 然而,有時候您可能會想要讓實驗室 VM 以特定順序啟動。 例如,若實驗室中的 Jumpbox VM 是其他 VM 的存取點,則該 Jumpbox VM 就必須在其他 VM 之前啟動。

必要條件

建立 PowerShell Runbook

  1. 在自動化帳戶的 [概觀] 頁面上,從左側功能表中選取 [Runbook]
  2. 在 [Runbook] 頁面上,選取 [建立 Runbook]
  3. 遵循使用受控識別建立自動化 PowerShell Runbook 中的指示,建立 PowerShell Runbook。 使用下列 PowerShell 指令碼填入 Runbook。

準備 PowerShell 指令碼

下列指令碼會採用訂閱名稱與實驗室名稱作為參數。 指令碼會取得實驗室中的所有 VM,並剖析其標籤資訊,以建立 VM 名稱與其啟動順序的清單。 指令碼會依序逐步解說清單並啟動 VM。

若特定順序號碼中有多部 VM,則這些 VM 會使用 PowerShell 作業以非同步方式啟動。 沒有標籤的 VM 會將其啟動值設定為 10,且根據預設為最後一個啟動。 指令碼會忽略具有 0 到 10 以外之標記值的任何 VM。

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

執行指令碼

  • 若要每日執行此指令碼,請在自動化帳戶中建立排程,並將排程連結至 Runbook

  • 在具有多個實驗室之數個訂閱的企業案例中,您可以將不同實驗室與訂閱的參數資訊儲存於檔案中。 將檔案傳遞給指令碼,而不是傳遞個別參數。

  • 此範例會使用 Azure 自動化來執行 PowerShell 指令碼,但您也可以使用其他選項,例如組建/發行管線

下一步