如何用PowerShell列出Azure存储账户landing容器internal目录的子目录
问题:获取Azure存储容器internal目录下的项目子目录失败
我有一段PowerShell脚本,用来筛选带Business标签、包含landing容器的Azure存储账户,同时获取存储容量等信息。现在需要列出landing容器下internal父目录里的所有项目子目录,但添加-Prefix "internal"参数后没得到预期结果,求解决。
原脚本
Connect-AzAccount -Tenant 'xxxxx' -UseDeviceAuthentication # 获取所有订阅 $subscriptions = Get-AzSubscription # 定义用于筛选的标签键 $tagKey = "Business" # 初始化存储结果的数组 $results = @() foreach ($subscription in $subscriptions) { # 设置当前订阅上下文 Set-AzContext -SubscriptionId $subscription.Id # 获取当前订阅中所有带指定标签的存储账户 $storageAccounts = Get-AzStorageAccount | Where-Object { $_.Tags.ContainsKey($tagKey) } foreach ($storageAccount in $storageAccounts) { # 获取存储账户的容量指标 $resourceId = "/subscriptions/$($subscription.Id)/resourceGroups/$($storageAccount.ResourceGroupName)/providers/Microsoft.Storage/storageAccounts/$($storageAccount.StorageAccountName)" $uri = "https://management.azure.com$resourceId/providers/Microsoft.Insights/metrics?api-version=2023-10-01&metricnames=UsedCapacity&aggregation=Average" try { $response = Invoke-AzRestMethod -Method Get -Uri $uri $metrics = $response.Content | ConvertFrom-Json $usedCapacityMetric = $metrics.value | Where-Object { $_.name.value -eq "UsedCapacity" } if ($usedCapacityMetric) { $averageCapacity = $usedCapacityMetric.timeseries.data.average | Measure-Object -Sum | Select-Object -ExpandProperty Sum } else { $averageCapacity = 0 } } catch { Write-Warning "获取存储账户指标失败: $($storageAccount.StorageAccountName)" $averageCapacity = 0 } $ctx = $storageAccount.Context $containers = Get-AzStorageContainer -Context $ctx | Where-Object { $_.Name -eq "landing" } foreach ($container in $containers) { $prefix = "internal" $blobs = Get-AzStorageBlob -Prefix "internal" -Container $container.Name -Context $ctx $directories = $blobs | ForEach-Object { $parts = $_.Name.Split('/') for ($i = 0; $i -lt $parts.Length - 1; $i++) { $parts[0..$i] -join '/' } } | Sort-Object -Unique $results += [PSCustomObject]@{ SubscriptionName = $subscription.Name ResourceGroup = $storageAccount.ResourceGroupName StorageAccount = $storageAccount.StorageAccountName ContainerName = $container.Name UsedCapacityInBytes = $averageCapacity TagName = $tagKey TagValue = $storageAccount.Tags[$tagKey] Directories = $directories -join ", " } } } # 输出结果 $results | Format-Table -AutoSize }
目录结构说明
目录层级为:landing容器下存在internal目录,internal目录下包含多个项目子目录(如projectA、projectB等),每个项目子目录下还有更深层级的文件或文件夹。
解决方案
原脚本的问题在于遍历所有blob后拆分路径会生成所有层级的目录(包括internal本身和更深层级的子目录),且未精准筛选internal下的直接项目子目录。可以通过直接操作存储目录来解决,修改后的关键代码如下:
修改后的脚本片段(替换原容器遍历部分)
$ctx = $storageAccount.Context $containers = Get-AzStorageContainer -Context $ctx | Where-Object { $_.Name -eq "landing" } foreach ($container in $containers) { # 精准定位internal目录下的直接子目录,前缀末尾加/避免匹配类似internalXYZ的目录 $directories = Get-AzStorageBlobDirectory -Container $container.Name -Context $ctx -Prefix "internal/" | ForEach-Object { # 去掉前缀internal/,仅保留项目子目录名称 $_.Name.Substring("internal/".Length) } | Where-Object { $_ -notmatch "/" } | # 过滤掉更深层级的子目录,只保留直接子目录 Sort-Object -Unique # 处理internal目录不存在的情况 if (-not $directories) { $directories = @() } $results += [PSCustomObject]@{ SubscriptionName = $subscription.Name ResourceGroup = $storageAccount.ResourceGroupName StorageAccount = $storageAccount.StorageAccountName ContainerName = $container.Name UsedCapacityInBytes = $averageCapacity TagName = $tagKey TagValue = $storageAccount.Tags[$tagKey] Directories = $directories -join ", " } }
修改说明
- 使用
Get-AzStorageBlobDirectory直接操作目录:比遍历所有blob更高效,直接针对目录进行查询 - 前缀使用
"internal/":确保只匹配internal目录下的内容,避免误匹配名称以internal开头的其他目录 - 过滤直接子目录:通过
Where-Object { $_ -notmatch "/" }确保只保留internal下的第一层项目子目录,排除更深层级的目录 - 处理空目录情况:当
internal目录不存在或没有子目录时,返回空数组避免异常
内容的提问来源于stack exchange,提问作者sudhir karamchand
相关产品推荐
相关产品推荐

