如何通过PowerShell自动化周末调整Azure订阅级VM与App Service以节约成本
Azure资源自动化启停/缩放的PowerShell落地方案
一、前置准备
- 安装Azure PowerShell核心模块:
Install-Module -Name Az -AllowClobber -Scope CurrentUser - 创建Azure服务主体(SPN),给它分配订阅级的VM Contributor和Web Contributor权限,用来实现无交互登录
- 配置SharePoint访问权限:用App注册获取Client ID和密钥,或者直接用PnP PowerShell模块,确保能读取团队负责人维护的资源需求列表(列表建议包含:资源类型、资源名称、资源组、执行动作、目标实例数(针对App Service))
二、核心脚本实现
1. 无交互登录Azure
用服务主体登录,适配自动化场景:
# 从Azure Automation凭据资产读取敏感信息,避免硬编码 $tenantId = "你的租户ID" $clientId = "你的SPN客户端ID" $clientSecret = ConvertTo-SecureString "你的SPN密钥" -AsPlainText -Force $cred = New-Object System.Management.Automation.PSCredential($clientId, $clientSecret) Connect-AzAccount -ServicePrincipal -Credential $cred -Tenant $tenantId
2. 读取SharePoint资源需求列表
用PnP PowerShell拉取列表数据:
# 安装PnP模块(首次执行) Install-Module -Name PnP.PowerShell -AllowClobber -Scope CurrentUser # 登录SharePoint站点 $siteUrl = "你的SharePoint站点URL" Connect-PnPOnline -Url $siteUrl -ClientId $clientId -ClientSecret $clientSecret # 获取列表数据并格式化字段 $resourceTasks = Get-PnPListItem -List "资源需求列表" | Select-Object ` @{Name='ResourceType'; Expression={$_["ResourceType"]}}, @{Name='ResourceName'; Expression={$_["ResourceName"]}}, @{Name='ResourceGroup'; Expression={$_["ResourceGroup"]}}, @{Name='Action'; Expression={$_["Action"]}}, @{Name='TargetCount'; Expression={$_["TargetInstanceCount"]}}
3. VM启停逻辑
针对列表中的VM执行启停,注意取消分配才能真正节约成本:
foreach ($task in $resourceTasks | Where-Object {$_.ResourceType -eq "VM"}) { switch ($task.Action) { "Stop" { # 取消分配VM,彻底停止计费 Stop-AzVM -ResourceGroupName $task.ResourceGroup -Name $task.ResourceName -Force -StayProvisioned $false -ErrorAction SilentlyContinue Write-Host "已取消分配VM: $($task.ResourceName) ($($task.ResourceGroup))" } "Start" { Start-AzVM -ResourceGroupName $task.ResourceGroup -Name $task.ResourceName -ErrorAction SilentlyContinue Write-Host "已启动VM: $($task.ResourceName) ($($task.ResourceGroup))" } } }
4. App Service缩放逻辑
支持实例数缩放或SKU级别调整:
foreach ($task in $resourceTasks | Where-Object {$_.ResourceType -eq "AppService"}) { $webAppPlan = Get-AzAppServicePlan -ResourceGroupName $task.ResourceGroup -Name (Get-AzWebApp -ResourceGroupName $task.ResourceGroup -Name $task.ResourceName).ServerFarmId.Split('/')[-1] switch ($task.Action) { "ScaleDown" { # 缩容到1个实例,也可调整SKU(比如从P2到P1) Set-AzAppServicePlan -ResourceGroupName $task.ResourceGroup -Name $webAppPlan.Name -NumberOfWorkers 1 Write-Host "已缩容App Service计划: $($webAppPlan.Name) 到1个实例" } "ScaleUp" { # 恢复到目标实例数 Set-AzAppServicePlan -ResourceGroupName $task.ResourceGroup -Name $webAppPlan.Name -NumberOfWorkers $task.TargetCount Write-Host "已扩容App Service计划: $($webAppPlan.Name) 到$($task.TargetCount)个实例" } } }
三、自动化调度
用Azure Automation实现定时执行:
- 创建Azure Automation账户,导入Az和PnP.PowerShell模块
- 将脚本上传为PowerShell Runbook,把敏感信息(如SPN密钥)存储为Automation的凭据资产,在脚本中调用
- 配置计划:周五下午执行停机/缩容脚本,周一上午执行启动/扩容脚本
四、关键注意事项
- 测试时先在非生产环境验证,避免影响业务
- 对有可用性集的VM,批量操作时可按可用性集分组处理
- 可以添加日志输出到Azure Monitor,方便排查执行异常
- 如果是虚拟机规模集(VMSS),用
Stop-AzVmss和Start-AzVmss命令,逻辑类似单VM
内容的提问来源于stack exchange,提问作者Dwara
相关产品推荐
相关产品推荐

