你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

使用 Azure 自动化定义开发测试实验室 VM 的启动顺序

本文介绍如何通过在 Azure 自动化中使用 PowerShell runbook 以特定顺序启动开发测试实验室虚拟机 (VM)。 此 PowerShell 脚本使用实验室 VM 上的标记,因此你可以在不更改脚本的情况下更改启动顺序。

开发测试实验室的自动启动功能可以将实验室 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 脚本,但也可使用生成/发布管道之类的其他选项。

后续步骤