适用于 PowerShell 7.0 及以上版本,需要 Az.DesktopVirtualization 模块
背景 Azure Virtual Desktop(AVD)是微软在 Azure 上托管的桌面和应用虚拟化服务,为企业提供了集中管理、弹性扩展的远程办公解决方案。随着混合办公模式的普及,越来越多的企业选择 AVD 来统一管理员工桌面环境,降低终端设备运维成本,同时满足数据安全与合规要求。
对于 IT 运维团队来说,AVD 的日常管理涉及主机池创建、会话主机扩缩容、用户会话监控与故障排查等多个环节。虽然 Azure Portal 提供了图形界面,但在批量操作、自动化流水线和 CI/CD 场景中,PowerShell 脚本依然是最高效的手段。微软提供的 Az.DesktopVirtualization 模块覆盖了 AVD 几乎全部管理操作,让我们可以用脚本实现从创建到运维的全生命周期管理。
本文将介绍三个典型的 AVD 管理场景:主机池与工作区配置、会话主机扩缩容、以及用户会话管理与诊断。每个场景都附带可直接运行的 PowerShell 脚本示例。
AVD 主机池与工作区管理 主机池(Host Pool)是 AVD 的核心资源,定义了一组提供桌面或远程应用的虚拟机。工作区(Workspace)则是将应用组呈现给用户的逻辑容器。下面的脚本演示如何一步到位地创建主机池、配置应用组,并将其注册到工作区。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 Install-Module -Name Az.DesktopVirtualization -Force -Scope CurrentUserImport-Module Az.DesktopVirtualizationConnect-AzAccount $ResourceGroup = "rg-avd-prod" $Location = "eastasia" $HostPoolName = "hp-desktop-prod" $WorkspaceName = "ws-prod" $rg = Get-AzResourceGroup -Name $ResourceGroup -ErrorAction SilentlyContinueif (-not $rg ) { New-AzResourceGroup -Name $ResourceGroup -Location $Location Write-Host "已创建资源组: $ResourceGroup " } $hostPool = New-AzWvdHostPool ` -ResourceGroupName $ResourceGroup ` -Name $HostPoolName ` -Location $Location ` -HostPoolType Pooled ` -LoadBalancerType DepthFirst ` -PreferredAppGroupType Desktop ` -MaxSessionLimit 10 ` -ValidationEnv :$false Write-Host "主机池已创建: $ ($hostPool .Name)" $appGroup = Get-AzWvdDesktop -ResourceGroupName $ResourceGroup ` -HostPoolName $HostPoolName $workspace = New-AzWvdWorkspace ` -ResourceGroupName $ResourceGroup ` -Name $WorkspaceName ` -Location $Location Register-AzWvdApplicationGroup ` -ResourceGroupName $ResourceGroup ` -WorkspaceName $WorkspaceName ` -ApplicationGroupPath $appGroup .Id Write-Host "工作区已创建并注册桌面应用组: $ ($workspace .Name)"
执行结果示例:
1 2 3 已创建资源组: rg-avd-prod 主机池已创建: hp-desktop-prod 工作区已创建并注册桌面应用组: ws-prod
创建完成后,可以在 Azure Portal 中看到主机池和工作区已关联。用户通过 AVD 客户端登录时,工作区中的应用组会自动呈现为可用的桌面会话。
会话主机管理与扩缩容 主机池创建后,需要向其中添加会话主机(Session Host)——也就是实际运行用户桌面的 Azure 虚拟机。在生产环境中,根据负载自动扩缩容是控制成本的关键。以下脚本展示了手动添加会话主机以及配置自动扩缩方案。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 $ResourceGroup = "rg-avd-prod" $HostPoolName = "hp-desktop-prod" $sessionHosts = Get-AzWvdSessionHost ` -ResourceGroupName $ResourceGroup ` -HostPoolName $HostPoolName $sessionHosts | Format-Table Name, Status, Sessions, AllowNewSession -AutoSize $drainHost = "hp-desktop-prod/avd-vm-001" Update-AzWvdSessionHost ` -ResourceGroupName $ResourceGroup ` -HostPoolName $HostPoolName ` -Name $drainHost ` -AllowNewSession :$false Write-Host "已对 $drainHost 启用 Drain 模式" $scalingPlan = New-AzWvdScalingPlan ` -ResourceGroupName $ResourceGroup ` -Name "scaling-weekday" ` -Location "eastasia" ` -TimeZone "China Standard Time" ` -Schedule @ ( @ { name = "weekday-workhours" daysOfWeek = @ ("Monday" , "Tuesday" , "Wednesday" , "Thursday" , "Friday" ) rampUpStartTime = @ { hour = 8 ; minute = 0 } rampUpLoadBalancingAlgorithm = "BreadthFirst" rampUpMinimumHostsPct = 30 rampUpCapacityThresholdPct = 60 peakStartTime = @ { hour = 9 ; minute = 0 } peakLoadBalancingAlgorithm = "DepthFirst" rampDownStartTime = @ { hour = 18 ; minute = 0 } rampDownLoadBalancingAlgorithm = "DepthFirst" rampDownMinimumHostsPct = 10 rampDownCapacityThresholdPct = 90 rampDownForceLogoffUsers = $false offPeakStartTime = @ { hour = 20 ; minute = 0 } offPeakLoadBalancingAlgorithm = "DepthFirst" } ) $hostPool = Update-AzWvdHostPool ` -ResourceGroupName $ResourceGroup ` -Name $HostPoolName ` -ScalingPlanId $scalingPlan .Id Write-Host "自动扩缩计划已关联到主机池: $HostPoolName "
执行结果示例:
1 2 3 4 5 6 7 8 Name Status Sessions AllowNewSession ---- ------ -------- --------------- hp-desktop-prod /avd-vm-001 Available 3 True hp-desktop-prod /avd-vm-002 Available 5 True hp-desktop-prod /avd-vm-003 Available 2 True 已对 hp-desktop-prod /avd-vm-001 启用 Drain 模式 自动扩缩计划已关联到主机池: hp-desktop-prod
Drain 模式是维护窗口的必备操作——开启后该主机不再接受新会话,但已连接的用户不受影响。运维人员可以等待现有会话自然结束,或通知用户保存工作后手动注销,再对虚拟机执行补丁更新。自动扩缩计划则根据工作时间段自动调整主机数量,避免夜间空闲虚拟机持续产生费用。
用户会话管理与故障排查 当用户报告远程桌面连接异常时,快速定位问题是运维效率的关键。Az.DesktopVirtualization 模块提供了会话查询、断开连接、强制注销等操作,结合诊断功能可以大幅缩短故障响应时间。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 $ResourceGroup = "rg-avd-prod" $HostPoolName = "hp-desktop-prod" $userSessions = Get-AzWvdUserSession ` -ResourceGroupName $ResourceGroup ` -HostPoolName $HostPoolName $userSessions | Format-Table ` @ {N="用户" ;E={$_ .ActiveDirectoryUserName}}, ` @ {N="会话主机" ;E={($_ .Name -split "/" )[1 ]}}, ` @ {N="会话状态" ;E={$_ .SessionState}}, ` @ {N="创建时间" ;E={$_ .CreateTime}} ` -AutoSize $targetUser = "user01@vichamp.com" $targetSession = $userSessions | Where-Object { $_ .ActiveDirectoryUserName -eq $targetUser } if ($targetSession ) { Write-Host "找到用户会话: $ ($targetSession .Name)" Remove-AzWvdUserSession ` -ResourceGroupName $ResourceGroup ` -HostPoolName $HostPoolName ` -SessionHostName ($targetSession .Name -split "/" )[1 ] ` -Id ($targetSession .Name -split "/" )[2 ] ` -Force Write-Host "已断开用户 $targetUser 的会话" } else { Write-Host "未找到用户 $targetUser 的活跃会话" } $diagnostic = Get-AzWvdHostPool ` -ResourceGroupName $ResourceGroup ` -Name $HostPoolName foreach ($host in (Get-AzWvdSessionHost ` -ResourceGroupName $ResourceGroup ` -HostPoolName $HostPoolName )) { $vmName = ($host .Name -split "/" )[1 ] $vm = Get-AzVM -ResourceGroupName $ResourceGroup -Name $vmName -Status $powerState = ($vm .Statuses | Where-Object { $_ .Code -match "PowerState" }).DisplayStatus Write-Host ("{0,-25} AVD状态: {1,-12} VM电源: {2,-12} 会话数: {3}" -f ` $vmName , $host .Status, $powerState , $host .Sessions) }
执行结果示例:
1 2 3 4 5 6 7 8 9 10 11 12 用户 会话主机 会话状态 创建时间 ---- ---- -------- -------- user01@vichamp.com avd-vm-001 Active 2026-03 -13 T09:15:22Z user02@vichamp.com avd-vm-001 Active 2026-03 -13 T09:32:45Z user03@vichamp.com avd-vm-002 Active 2026-03 -13 T10:01:33Z 找到用户会话: hp-desktop-prod/avd-vm-001 /user01@vichamp.com 已断开用户 user01@vichamp.com 的会话 avd-vm-001 AVD状态: Available VM电源: VM running 会话数: 4 avd-vm-002 AVD状态: Available VM电源: VM running 会话数: 6 avd-vm-003 AVD状态: Available VM电源: VM running 会话数: 2
会话查询和诊断是排查 AVD 问题的第一步。当用户反馈桌面卡顿或无法连接时,先检查会话状态和主机负载,再决定是断开会话、注销用户还是扩容主机池,形成标准化的故障处理流程。
注意事项
模块版本兼容性 :Az.DesktopVirtualization 模块更新频繁,建议定期执行 Update-Module Az.DesktopVirtualization 获取最新功能和修复。部分 cmdlet 在不同版本间参数名称可能有变化,升级后需回归测试现有脚本。
权限要求 :执行 AVD 管理操作需要 Azure RBAC 角色授权。推荐使用”Desktop Virtualization Contributor”内置角色,而非 Owner,以遵循最小权限原则。生产环境中应通过 Azure PIM(Privileged Identity Management)实现即时提权。
Drain 模式使用时机 :在执行安全补丁、应用更新或故障排查前,务必先开启 Drain 模式。注意 AllowNewSession:$false 只阻止新连接,不会断开已有会话。如需强制迁移用户,应先通知用户保存工作,再使用 Remove-AzWvdUserSession 注销。
自动扩缩计划配置 :扩缩计划的 rampUpMinimumHostsPct 参数决定了启动阶段最少开启的主机百分比,设置过低会导致用户在高峰时段排队等待;设置过高则增加闲置成本。建议根据历史负载数据调优,并利用 AVD Insights 监控仪表盘持续观察效果。
会话主机网络要求 :AVD 会话主机必须加入 Azure AD(或 Microsoft Entra ID)域,并开通到 AVD 控制平面的出站 HTTPS(443 端口)连接。如果使用自定义 VNet,需确保 DNS 解析和网络安全组规则正确配置,否则主机注册会失败。
诊断日志 :建议在主机池上启用 Azure Monitor 诊断设置,将连接日志、错误日志、管理日志发送到 Log Analytics 工作区。结合 KQL 查询可以实现连接失败告警、用户登录趋势分析等高级运维场景,大幅缩短 MTTR(平均恢复时间)。