使用 Azure 自动化和 Azure 逻辑应用为 Azure 虚拟桌面设置缩放工具

在本文中,你将了解缩放工具,此工具在 Azure 虚拟桌面环境中使用 Azure 自动化运行手册和 Azure 逻辑应用自动缩放会话主机 VM。 若要了解有关缩放工具的详细信息,请参阅使用 Azure 自动化和 Azure Logic 应用缩放会话主机

先决条件

开始设置缩放工具之前,请确保已准备好以下内容:

  • 一个 Azure 虚拟桌面主机池
  • 已配置了 Azure 虚拟桌面服务并向其注册了的会话主机池 VM。
  • 在 Azure 订阅上分配有基于角色的访问控制 (RBAC) 参与者角色的用户,用来创建资源。 你还需要具有“应用程序管理员”和/或“所有者”RBAC 角色,以创建托管标识。
  • Log Analytics 工作区(可选)。

用于部署此工具的计算机必须具有:

如果一切已准备就绪,现在就可以开始了。

创建或更新 Azure 自动化帐户

注意

如果你已有 Azure 自动化帐户,并且其中包含运行较旧版本缩放脚本的 runbook,则你只需按照以下说明进行操作,确保更新该帐户。

首先,你需要一个 Azure 自动化帐户来运行 PowerShell runbook。 即使具有要用于设置 PowerShell runbook 的现有 Azure 自动化帐户,本部分介绍的过程也是有效的。 设置方式如下:

  1. 打开 PowerShell。

  2. 运行以下 cmdlet 登录到 Azure 帐户。

    Connect-AzAccount -Environment AzureChinaCloud
    

    注意

    你的帐户对要在其上部署缩放工具的 Azure 订阅必须具有参与者权限。

  3. 运行以下 cmdlet,下载用于创建 Azure 自动化帐户的脚本:

    New-Item -ItemType Directory -Path "C:\Temp" -Force
    Set-Location -Path "C:\Temp"
    $Uri = "https://raw.githubusercontent.com/Azure/RDS-Templates/master/wvd-templates/wvd-scaling-script/CreateOrUpdateAzAutoAccount.ps1"
    # Download the script
    Invoke-WebRequest -Uri $Uri -OutFile ".\CreateOrUpdateAzAutoAccount.ps1"
    
  4. 运行以下 cmdlet 以执行脚本并创建 Azure 自动化帐户。 可以填写参数的值,也可以对其进行注释以使用其默认值。

    $Params = @{
         "AADTenantId"           = "<Azure_Active_Directory_tenant_ID>"   # Optional. If not specified, it will use the current Azure context
         "SubscriptionId"        = "<Azure_subscription_ID>"              # Optional. If not specified, it will use the current Azure context
         "UseARMAPI"             = $true
         "ResourceGroupName"     = "<Resource_group_name>"                # Optional. Default: "WVDAutoScaleResourceGroup"
         "AutomationAccountName" = "<Automation_account_name>"            # Optional. Default: "WVDAutoScaleAutomationAccount"
         "Location"              = "<Azure_region_for_deployment>"
         "WorkspaceName"         = "<Log_analytics_workspace_name>"       # Optional. If specified, Log Analytics will be used to configure the custom log table that the runbook PowerShell script can send logs to
    }
    
    .\CreateOrUpdateAzAutoAccount.ps1 @Params
    

    注意

    如果策略不允许在特定区域中创建缩放脚本资源,请更新策略分配,并将所需区域添加到允许区域列表。

  5. 如果之前未创建自动化帐户,则 cmdlet 的输出将包括自动化帐户变量中加密的 Webhook URI。 请务必保留一份 URI 的记录,因为在为 Azure 逻辑应用设置执行计划时需要使用它作为参数。 如果要更新现有自动化帐户,可以使用 PowerShell 访问变量检索 Webhook URI。

  6. 如果为 Log Analytics 指定了参数 WorkspaceName,则 cmdlet 的输出还将包含 Log Analytics 工作区 ID 及其主键。 记下工作区 ID 和主键,因为稍后在为 Azure 逻辑应用设置执行计划时,需要再次将它们与参数一起使用。

  7. 设置 Azure 自动化帐户后,登录到 Azure 订阅,并检查以确保 Azure 自动化帐户和相关 runbook 已显示在指定的资源组中,如下图所示:

    An image of the Azure overview page showing the newly created Azure Automation account and runbook.

    若要检查 webhook 是否位于其预期位置,请选择 runbook 的名称。 接下来,转到 runbook 的“资源”部分,选择“Webhook”。

创建托管标识

现在,你已拥有 Azure 自动化帐户,还需要设置托管标识(如果尚未设置)。 托管标识将帮助 Runbook 访问其他与 Microsoft Entra 相关的资源,并对重要的自动化过程进行身份验证。

要设置托管标识,请按照将系统分配的托管标识用于 Azure 自动化帐户中的说明进行操作。 创建托管标识后,请向 Azure 虚拟桌面资源(例如主机池、VM 等)分配该标识和相应的参与者权限。完成后,返回到本文并创建 Azure 逻辑应用和执行计划,以完成初始设置过程。

创建 Azure 逻辑应用和执行计划

最后,需要创建 Azure 逻辑应用,并为新的缩放工具设置执行计划。 首先,下载并导入桌面虚拟 PowerShell 模块(如果尚未这样做),以便在 PowerShell 会话中使用。

  1. 打开 PowerShell。

  2. 运行以下 cmdlet 登录到 Azure 帐户。

    Connect-AzAccount -Environment AzureChinaCloud
    
  3. 运行以下 cmdlet,下载用于创建 Azure 逻辑应用的脚本。

    New-Item -ItemType Directory -Path "C:\Temp" -Force
    Set-Location -Path "C:\Temp"
    $Uri = "https://raw.githubusercontent.com/Azure/RDS-Templates/master/wvd-templates/wvd-scaling-script/CreateOrUpdateAzLogicApp.ps1"
    # Download the script
    Invoke-WebRequest -Uri $Uri -OutFile ".\CreateOrUpdateAzLogicApp.ps1"
    
  4. 运行以下 PowerShell 脚本,以便为主机池创建 Azure 逻辑应用和执行计划

    注意

    需要为要自动缩放的每个主机池运行此脚本,但只需要一个 Azure 自动化帐户。

    $AADTenantId = (Get-AzContext).Tenant.Id
    
    $AzSubscription = Get-AzSubscription | Out-GridView -OutputMode:Single -Title "Select your Azure Subscription"
    Select-AzSubscription -Subscription $AzSubscription.Id
    
    $ResourceGroup = Get-AzResourceGroup | Out-GridView -OutputMode:Single -Title "Select the resource group for the new Azure Logic App"
    
    $WVDHostPool = Get-AzResource -ResourceType "Microsoft.DesktopVirtualization/hostpools" | Out-GridView -OutputMode:Single -Title "Select the host pool you'd like to scale"
    
    $LogAnalyticsWorkspaceId = Read-Host -Prompt "If you want to use Log Analytics, enter the Log Analytics Workspace ID returned by when you created the Azure Automation account, otherwise leave it blank"
    $LogAnalyticsPrimaryKey = Read-Host -Prompt "If you want to use Log Analytics, enter the Log Analytics Primary Key returned by when you created the Azure Automation account, otherwise leave it blank"
    $RecurrenceInterval = Read-Host -Prompt "Enter how often you'd like the job to run in minutes, e.g. '15'"
    $BeginPeakTime = Read-Host -Prompt "Enter the start time for peak hours in local time, e.g. 9:00"
    $EndPeakTime = Read-Host -Prompt "Enter the end time for peak hours in local time, e.g. 18:00"
    $TimeDifference = Read-Host -Prompt "Enter the time difference between local time and UTC in hours, e.g. +5:30"
    $SessionThresholdPerCPU = Read-Host -Prompt "Enter the maximum number of sessions per CPU that will be used as a threshold to determine when new session host VMs need to be started during peak hours"
    $MinimumNumberOfRDSH = Read-Host -Prompt "Enter the minimum number of session host VMs to keep running during off-peak hours"
    $MaintenanceTagName = Read-Host -Prompt "Enter the name of the Tag associated with VMs you don't want to be managed by this scaling tool"
    $LimitSecondsToForceLogOffUser = Read-Host -Prompt "Enter the number of seconds to wait before automatically signing out users. If set to 0, any session host VM that has user sessions, will be left untouched"
    $LogOffMessageTitle = Read-Host -Prompt "Enter the title of the message sent to the user before they are forced to sign out"
    $LogOffMessageBody = Read-Host -Prompt "Enter the body of the message sent to the user before they are forced to sign out"
    
    $WebhookURI = Read-Host -Prompt "Enter the webhook URI that has already been generated for this Azure Automation account. The URI is stored as encrypted in the above Automation Account variable. To retrieve the value, see https://learn.microsoft.com/azure/automation/shared-resources/variables?tabs=azure-powershell#powershell-cmdlets-to-access-variables"
    
    $Params = @{
         "AADTenantId"                   = $AADTenantId                             # Optional. If not specified, it will use the current Azure context
         "SubscriptionID"                = $AzSubscription.Id                       # Optional. If not specified, it will use the current Azure context
         "ResourceGroupName"             = $ResourceGroup.ResourceGroupName         # Optional. Default: "WVDAutoScaleResourceGroup"
         "Location"                      = $ResourceGroup.Location                  # Optional. Default: "China North 2"
         "UseARMAPI"                     = $true
         "HostPoolName"                  = $WVDHostPool.Name
         "HostPoolResourceGroupName"     = $WVDHostPool.ResourceGroupName           # Optional. Default: same as ResourceGroupName param value
         "LogAnalyticsWorkspaceId"       = $LogAnalyticsWorkspaceId                 # Optional. If not specified, script will not log to the Log Analytics
         "LogAnalyticsPrimaryKey"        = $LogAnalyticsPrimaryKey                  # Optional. If not specified, script will not log to the Log Analytics
         "RecurrenceInterval"            = $RecurrenceInterval                      # Optional. Default: 15
         "BeginPeakTime"                 = $BeginPeakTime                           # Optional. Default: "09:00"
         "EndPeakTime"                   = $EndPeakTime                             # Optional. Default: "17:00"
         "TimeDifference"                = $TimeDifference                          # Optional. Default: "-7:00"
         "SessionThresholdPerCPU"        = $SessionThresholdPerCPU                  # Optional. Default: 1
         "MinimumNumberOfRDSH"           = $MinimumNumberOfRDSH                     # Optional. Default: 1
         "MaintenanceTagName"            = $MaintenanceTagName                      # Optional.
         "LimitSecondsToForceLogOffUser" = $LimitSecondsToForceLogOffUser           # Optional. Default: 1
         "LogOffMessageTitle"            = $LogOffMessageTitle                      # Optional. Default: "Machine is about to shutdown."
         "LogOffMessageBody"             = $LogOffMessageBody                       # Optional. Default: "Your session will be logged off. Please save and close everything."
         "WebhookURI"                    = $WebhookURI
    }
    
    .\CreateOrUpdateAzLogicApp.ps1 @Params
    

    运行该脚本后,资源组中应会显示 Azure 逻辑应用,如下图所示。

    An image of the overview page for an example Azure Logic App.

    若要更改执行计划(例如更改重复周期间隔或时区),可转到 Azure 逻辑应用自动缩放计划程序,然后选择“编辑”以转到 Azure 逻辑应用设计器

    An image of the Azure Logic App Designer. The Recurrence and webhook menus that let the user edit recurrence times and the webhook file are open.

管理缩放工具

现在已创建缩放工具,可以访问其输出了。 本部分介绍可能对你有所帮助的一些功能。

查看作业状态

可以查看所有 runbook 作业的概述性状态或在 Azure 门户中深入了解特定 runbook 作业的状态和情况。

在所选的 Azure 自动化帐户右侧,可在“作业统计信息”下查看所有 runbook 作业的摘要列表。 在窗口左侧打开“作业”页后,其中会显示当前作业状态、开始时间和完成时间。

A screenshot of the job status page.

查看日志和缩放工具输出

可以通过打开 runbook 并选择作业来查看横向扩展和横向缩减操作的日志。

在托管 Azure 自动化帐户的资源组中,导航到 runbook,并选择“概述”。 在概述页面,选择“最近的作业”下的某个作业,并查看其缩放工具输出,如下图所示。

An image of the output window for the scaling tool.

检查 runbook 脚本版本号

可以通过在 Azure 自动化帐户中打开 runbook 文件并选择“查看”来检查正在使用的 runbook 脚本的版本。 Runbook 的脚本将显示在屏幕的右侧。 在该脚本中,版本号以 v#.#.# 格式显示在 SYNOPSIS 部分的下方。 可以从此处获取最新版本号。 如果未在 runbook 脚本中看到版本号,则表示你运行的是早期版本的脚本,并且应立即更新此脚本。 如果需要更新 runbook 脚本,请按照创建或更新 Azure 自动化帐户中的说明进行操作。

报告问题

报告问题时,需要提供以下信息来帮助我们进行故障排除:

  • 导致问题的作业中“所有日志”选项卡中的完整日志。 若要了解如何获取日志,请按照查看日志和缩放工具输出中的说明进行操作。 如果日志中包含任何敏感或私人信息,可以先删除这些信息,然后再向我们提交问题。

  • 正在使用的 runbook 脚本的版本。 若要了解如何获取版本号,请参阅检查 runbook 脚本版本号

  • Azure 自动化帐户中安装的以下每个 PowerShell 模块的版本号。 若要查找这些模块,请打开 Azure 自动化帐户,选择窗口左侧窗格中“共享资源”部分下的“模块”,然后搜索模块的名称 。

    • Az.Accounts
    • Az.Compute
    • Az.Resources
    • Az.Automation
    • OMSIngestionAPI
    • Az.DesktopVirtualization

Log Analytics

如果决定使用 Log Analytics,可以在 Log Analytics 工作区的“日志”视图中的“自定义日志”下查看名为 WVDTenantScale_CL 的自定义日志中的所有日志数据 。 我们列出了一些可能有用的示例查询。

  • 若要查看主机池的所有日志,请输入以下查询:

    WVDTenantScale_CL
    | where hostpoolName_s == "<host_pool_name>"
    | project TimeStampUTC = TimeGenerated, TimeStampLocal = TimeStamp_s, HostPool = hostpoolName_s, LineNumAndMessage = logmessage_s, AADTenantId = TenantId
    
  • 若要查看主机池中当前正在运行的会话主机 VM 和活动用户会话总数,请输入以下查询:

    WVDTenantScale_CL
    | where logmessage_s contains "Number of running session hosts:"
         or logmessage_s contains "Number of user sessions:"
         or logmessage_s contains "Number of user sessions per Core:"
    | where hostpoolName_s == "<host_pool_name>"
    | project TimeStampUTC = TimeGenerated, TimeStampLocal = TimeStamp_s, HostPool = hostpoolName_s, LineNumAndMessage = logmessage_s, AADTenantId = TenantId
    
  • 若要查看主机池中所有会话主机 VM 的状态,请输入以下查询:

    WVDTenantScale_CL
    | where logmessage_s contains "Session host:"
    | where hostpoolName_s == "<host_pool_name>"
    | project TimeStampUTC = TimeGenerated, TimeStampLocal = TimeStamp_s, HostPool = hostpoolName_s, LineNumAndMessage = logmessage_s, AADTenantId = TenantId
    
  • 若要查看任何错误和警告,请输入以下查询:

    WVDTenantScale_CL
    | where logmessage_s contains "ERROR:" or logmessage_s contains "WARN:"
    | project TimeStampUTC = TimeGenerated, TimeStampLocal = TimeStamp_s, HostPool = hostpoolName_s, LineNumAndMessage = logmessage_s, AADTenantId = TenantId
    

限制

使用此缩放脚本时,缩放会话主机 VM 存在一些限制:

  • 缩放脚本不考虑标准时间和夏令时之间的时间变化。