You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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 ", "
    }
}

修改说明

  1. 使用Get-AzStorageBlobDirectory直接操作目录:比遍历所有blob更高效,直接针对目录进行查询
  2. 前缀使用"internal/":确保只匹配internal目录下的内容,避免误匹配名称以internal开头的其他目录
  3. 过滤直接子目录:通过Where-Object { $_ -notmatch "/" }确保只保留internal下的第一层项目子目录,排除更深层级的目录
  4. 处理空目录情况:当internal目录不存在或没有子目录时,返回空数组避免异常

内容的提问来源于stack exchange,提问作者sudhir karamchand

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 00:43:13