如何通过AZ CLI获取Azure App Service应用及识别孤立资源
你的现有脚本存在几个问题,没法正确识别孤立的App Service Plan:
- TSV格式的
$app_service_plans循环时,没拆分出计划名称和资源组,${resource_group}和${plan_name}这两个变量根本没定义,会直接报错 - 只统计了Web App,但Function App同样会占用App Service Plan,漏统计会导致误判部分计划为孤立
- 最后没有对比筛选出关联App数量为0的计划,等于只做了统计步骤没输出结果
下面是完整的实现方案,包含孤立App Service Plan和孤立存储账户的识别:
一、识别孤立的App Service Plan
步骤说明
- 登录Azure并指定目标订阅(如果有多个订阅,可循环遍历)
- 获取所有App Service Plan的完整信息(包含ID、名称、资源组)
- 获取所有依赖App Service Plan的资源:Web App + Function App,提取它们关联的Plan ID
- 对比找出没有被任何App引用的Plan,即为孤立计划
完整脚本
# 登录Azure(如果未登录的话) az login # 指定要检查的订阅ID(如果有多个订阅,可改为循环遍历az account list的结果) $subscriptionId = "你的订阅ID" az account set --subscription $subscriptionId # 获取所有App Service Plan,保存为对象数组 $allPlans = az appservice plan list --query "[].{Id:id, Name:name, ResourceGroup:resourceGroup}" --output json | ConvertFrom-Json # 获取所有Web App和Function App关联的Plan ID $usedPlanIds = @() # 收集Web App的Plan ID $webAppPlans = az webapp list --query "[].serverFarmId" --output json | ConvertFrom-Json $usedPlanIds += $webAppPlans # 收集Function App的Plan ID $functionAppPlans = az functionapp list --query "[].serverFarmId" --output json | ConvertFrom-Json $usedPlanIds += $functionAppPlans # 去重,避免重复统计 $usedPlanIds = $usedPlanIds | Where-Object { $_ -ne $null } | Select-Object -Unique # 筛选孤立的App Service Plan $orphanedPlans = $allPlans | Where-Object { $usedPlanIds -notcontains $_.Id } # 输出结果 Write-Host "=== 孤立的App Service Plan ===" $orphanedPlans | Format-Table Name, ResourceGroup, Id -AutoSize
二、识别孤立的存储账户
步骤说明
- 获取所有存储账户的完整信息
- 查询所有引用存储账户的资源(通过资源的属性中是否包含存储账户ID/连接字符串来判断)
- 找出没有被任何资源引用的存储账户,即为孤立账户
完整脚本
# 获取所有存储账户 $allStorageAccounts = az storage account list --query "[].{Id:id, Name:name, ResourceGroup:resourceGroup}" --output json | ConvertFrom-Json # 存储已被使用的存储账户ID $usedStorageIds = @() # 查询所有可能引用存储账户的资源(这里覆盖常见场景:Web App、Function App) # 1. Web App配置中的存储账户 $webAppStorageRefs = az webapp config appsettings list --query "[?value contains('AccountName=')].value" --output json | ConvertFrom-Json foreach ($ref in $webAppStorageRefs) { $accountName = ($ref -split "AccountName=")[1] -split ";" | Select-Object -First 1 if ($accountName) { $storageId = $allStorageAccounts | Where-Object { $_.Name -eq $accountName } | Select-Object -ExpandProperty Id if ($storageId) { $usedStorageIds += $storageId } } } # 2. Function App的存储账户 $functionAppStorageRefs = az functionapp config appsettings list --query "[?name=='AzureWebJobsStorage'].value" --output json | ConvertFrom-Json foreach ($ref in $functionAppStorageRefs) { $accountName = ($ref -split "AccountName=")[1] -split ";" | Select-Object -First 1 if ($accountName) { $storageId = $allStorageAccounts | Where-Object { $_.Name -eq $accountName } | Select-Object -ExpandProperty Id if ($storageId) { $usedStorageIds += $storageId } } } # 去重 $usedStorageIds = $usedStorageIds | Select-Object -Unique # 筛选孤立的存储账户 $orphanedStorageAccounts = $allStorageAccounts | Where-Object { $usedStorageIds -notcontains $_.Id } # 输出结果 Write-Host "`n=== 孤立的存储账户 ===" $orphanedStorageAccounts | Format-Table Name, ResourceGroup, Id -AutoSize
补充说明
- 存储账户的引用场景很多,上面的脚本覆盖了最常见的Web App和Function App场景,如果需要更全面,可以补充查询其他资源类型(比如逻辑应用、机器学习工作区等)
- 如果是多订阅场景,需要在外层套一个订阅循环,遍历所有订阅执行上述逻辑
内容的提问来源于stack exchange,提问作者Fiona
相关产品推荐
相关产品推荐

