使用 PowerShell 管理 blob 容器

Azure blob 存储允许存储大量非结构化对象数据。 你可以使用 Blob 存储来收集媒体、内容或应用程序数据或者将其公开给用户。 由于所有 blob 数据都存储在容器中,因此必须先创建存储容器,然后才能开始上传数据。 要详细了解 Blob 存储,请参阅 Azure Blob 存储简介

本操作指南文章介绍了如何使用单个和多个存储容器对象。

先决条件

需要先获得对 Azure 订阅的授权,然后才能使用本文中的示例。 可以通过使用 Microsoft Entra 帐户进行身份验证或使用共享密钥进行授权。 本文中的示例将 Microsoft Entra 身份验证与上下文对象结合使用。 上下文对象封装你的 Microsoft Entra 凭据并将其传递给后续数据操作,从而消除了重新身份验证的需要。

若要使用 Microsoft Entra 帐户登录到你的 Azure 帐户,请打开 PowerShell 并调用 Connect-AzAccount cmdlet。

# Connect to your Azure subscription
 Connect-AzAccount -Environment AzureChinaCloud

建立连接后,通过调用 New-AzStorageContext cmdlet 创建存储帐户上下文。 包含 -UseConnectedAccount 参数,以便使用 Microsoft Entra 凭据执行数据操作。

# Create a context object using Azure AD credentials
 $ctx = New-AzStorageContext -StorageAccountName <storage account name> -UseConnectedAccount

请记得将括号中的占位符值替换为你自己的值。 若要详细了解如何使用 PowerShell 登录 Azure,请参阅使用 Azure PowerShell 登录

创建容器

若要使用 PowerShell 创建容器,请调用 New-AzStorageContainer cmdlet。 可以在存储帐户中创建的 blob 或容器的数量没有限制。 容器不能嵌套在其他容器中。

以下示例说明了使用 New-AzStorageContainer cmdlet 创建 blob 容器的三个选项。 第一种方法创建单个容器,而其余两种方法利用 PowerShell 操作来自动创建容器。

若要使用此示例,请提供变量值并确保已创建与 Azure 订阅的连接。 请记得将括号中的占位符值替换为你自己的值。

# Create variables
 $containerName  = "individual-container"
 $prefixName     = "loop"

# Approach 1: Create a container
 New-AzStorageContainer -Name $containerName -Context $ctx

# Approach 2: Create containers with a PowerShell loop
 for ($i = 1; $i -le 3; $i++) { 
     New-AzStorageContainer -Name (-join($prefixName, $i)) -Context $ctx
    } 

# Approach 3: Create containers using the PowerShell Split method
 "$($prefixName)4 $($prefixName)5 $($prefixName)6".split() | New-AzStorageContainer -Context $ctx

结果提供存储帐户的名称并确认新容器的创建。

Storage Account Name: demostorageaccount

Name                   PublicAccess   LastModified
----                   ------------   ------------
individual-container   Off            11/2/2021 4:09:05 AM +00:00
loop-container1        Off            11/2/2021 4:09:05 AM +00:00
loop-container2        Off            11/2/2021 4:09:05 AM +00:00
loop-container3        Off            11/2/2021 4:09:05 AM +00:00           
loop-container4        Off            11/2/2021 4:09:05 AM +00:00           
loop-container5        Off            11/2/2021 4:09:05 AM +00:00           
loop-container6        Off            11/2/2021 4:09:05 AM +00:00          

列出容器

使用 Get-AzStorageContainer cmdlet 检索存储容器。 若要检索单个容器,请包含 -Name 参数。 要返回以给定字符串开头的容器列表,请为 -Prefix 参数指定值。

以下示例检索单个容器和容器资源列表。

# Create variables
 $containerName  = "individual-container"
 $prefixName     = "loop-"

# Approach 1: Retrieve an individual container
 Get-AzStorageContainer -Name $containerName -Context $ctx
 Write-Host

# Approach 2: Retrieve a list of containers
 Get-AzStorageContainer -Prefix $prefixName -Context $ctx

结果提供 blob 终结点的 URI,并列出了按名称和前缀检索到的容器。

   Storage Account Name: demostorageaccount

Name                 PublicAccess         LastModified                   IsDeleted  VersionId        
----                 ------------         ------------                   ---------  ---------        
individual-container                      11/2/2021 5:52:08 PM +00:00                                

loop-container1                           11/2/2021 12:22:00 AM +00:00                               
loop-container2                           11/2/2021 12:22:00 AM +00:00                               

loop-container1                           11/2/2021 12:22:00 AM +00:00                               
loop-container2                           11/2/2021 12:22:00 AM +00:00
loop-container3                           11/2/2021 12:22:00 AM +00:00   True       01D7E7129FDBD7D4
loop-container4                           11/2/2021 12:22:00 AM +00:00   True       01D7E8A5EF01C787 

读取容器属性和元数据

容器公开系统属性和用户定义的元数据。 每个 Blob 存储资源都提供系统属性。 有些属性是只读的,而其他属性可以读取或设置。 事实上,有些系统属性与某些标准 HTTP 头对应。

用户定义的元数据由你为 Blob 存储资源指定的一个或多个名称/值对组成。 可以使用元数据存储资源的其他值。 元数据值仅用于你自己的目的,不会影响资源的行为方式。

容器属性

下面的示例检索带有 demo 前缀的所有容器,并对其进行循环访问,列出其属性。

# Create variable
 $prefix = "loop"

# Get containers
 $containers = Get-AzStorageContainer -Prefix $prefix -Context $ctx

# Iterate containers, display properties
 Foreach ($container in $containers) 
 {
    $containerProperties = $container.BlobContainerClient.GetProperties()
    Write-Host $container.Name "properties:"
    $containerProperties.Value
 }

结果显示具有 loop 前缀的所有容器并列出其属性。

loop-container1 properties:

LastModified                      : 12/7/2021 7:47:17 PM +00:00
LeaseStatus                       : Unlocked
LeaseState                        : Available
LeaseDuration                     : Infinite
PublicAccess                      : 
HasImmutabilityPolicy             : False
HasLegalHold                      : False
DefaultEncryptionScope            : $account-encryption-key
PreventEncryptionScopeOverride    : False
DeletedOn                         : 
RemainingRetentionDays            : 
ETag                              : 0x8D9B9BA602806DA
Metadata                          : {}
HasImmutableStorageWithVersioning : False

loop-container2 properties:
LastModified                      : 12/7/2021 7:47:18 PM +00:00
LeaseStatus                       : Unlocked
LeaseState                        : Available
LeaseDuration                     : Infinite
PublicAccess                      : 
HasImmutabilityPolicy             : False
HasLegalHold                      : False
DefaultEncryptionScope            : $account-encryption-key
PreventEncryptionScopeOverride    : False
DeletedOn                         : 
RemainingRetentionDays            : 
ETag                              : 0x8D9B9BA605996AE
Metadata                          : {}
HasImmutableStorageWithVersioning : False

读取和写入容器元数据

在其存储帐户中拥有数千个对象的用户可以根据其元数据快速查找特定容器。 若要访问元数据,将使用 BlobContainerClient 对象。 此对象允许你访问和操作容器及其 blob。 若要更新元数据,需要调用 SetMetadata() 方法。 方法只接受存储在泛型 IDictionary 对象中的键值对。 有关详细信息,请参阅 BlobContainerClient 类

下面的示例首先更新容器的元数据,然后检索容器的元数据。 该示例从内存中刷新示例容器,并再次检索它,以确保不会从内存中的对象读取元数据。

# Create variable
  $containerName = "individual-container"

# Retrieve container
 $container = Get-AzStorageContainer -Name $containerName -Context $ctx

# Create IDictionary, add key-value metadata pairs to IDictionary
 $metadata = New-Object System.Collections.Generic.Dictionary"[String,String]"
 $metadata.Add("CustomerName","Anthony Bennedetto")
 $metadata.Add("CustomerDOB","08/03/1926")
 $metadata.Add("CustomerBirthplace","Long Island City")

# Update metadata
  $container.BlobContainerClient.SetMetadata($metadata, $null)

# Flush container from memory, retrieve updated container
 $container = $null
 $container = Get-AzStorageContainer -Name $containerName -Context $ctx
 
# Display metadata
 $properties = $container.BlobContainerClient.GetProperties()
 Write-Host $container.Name "metadata:" 
 Write-Host $properties.Value.Metadata

结果显示容器的完整元数据。

individual-container metadata:

[CustomerName, Anthony Bennedetto] [CustomerDOB, 08/03/1926] [CustomerBirthplace, Long Island City]

获取容器的共享访问签名

共享访问签名 (SAS) 提供对 Azure 资源的委托访问权限。 使用 SAS 可以精细控制客户端访问数据的方式。 例如,可以指定客户端可用的资源。 还可以限制客户端可以执行的操作类型,并指定允许执行操作的时间。

SAS 通常用于为通常没有权限的客户端提供临时和安全的访问权限。 这种情况的一个示例是允许用户将其自己的数据读取和写入你的存储帐户的服务。

Azure 存储支持三种类型的共享访问签名:用户委托、服务和帐户 SAS。 有关共享访问签名的详细信息,请参阅为容器或 blob 创建服务 SAS文。

注意

拥有有效 SAS 的任何客户端都可以访问该 SAS 允许的存储帐户中的数据。 防止 SAS 被恶意使用或意料之外的使用很重要。 请谨慎分发 SAS,并制定撤销受到安全威胁的 SAS 的计划。

下面的示例说明了如何使用 New-AzStorageContainerSASToken cmdlet 为特定容器配置服务 SAS。 该示例将使用开始时间和到期时间以及协议配置 SAS。 它还使用 -Permission 参数指定 SAS 中的读取、写入和列出权限 。 可以参考创建服务 SAS 一文中的完整权限表。

# Create variables
 $accountName   = "<storage-account>"
 $containerName = "individual-container"
 $startTime     = Get-Date
 $expiryTime    = $startTime.AddDays(7)
 $permissions   = "rwl"
 $protocol      = "HttpsOnly"

# Create a context object using Azure AD credentials, retrieve container
 $ctx = New-AzStorageContext -StorageAccountName $accountName -UseConnectedAccount
 
# Approach 1: Generate SAS token for a specific container
 $sas = New-AzStorageContainerSASToken `
 -Context $ctx `
 -Name $containerName `
 -StartTime $startTime `
 -ExpiryTime $expiryTime `
 -Permission $permissions `
 -Protocol $protocol

# Approach 2: Generate SAS tokens for a container list using pipeline
  Get-AzStorageContainer -Container $filterName -Context $ctx | New-AzStorageContainerSASToken `
 -Context $ctx `
 -StartTime $startTime `
 -ExpiryTime $expiryTime `
 -Permission $permissions `
 -Protocol $protocol | Write-Output

注意

Blob 存储返回的 SAS 令牌不包含 URL 查询字符串的分隔符字符 ('?')。 如果要将 SAS 令牌追加到资源 URL,请记住还要追加分隔符。

删除容器

根据用例,可以使用 Remove-AzStorageContainer cmdlet 删除容器或容器列表。 删除容器列表时,可以利用条件操作、循环或 PowerShell 管道,如以下示例所示。

# Create variables
 $accountName    = "<storage-account>"
 $containerName  = "individual-container"
 $prefixName     = "loop-"

# Delete a single named container
 Remove-AzStorageContainer -Name $containerName -Context $ctx

# Iterate a loop, deleting containers
 for ($i = 1; $i -le 2; $i++) { 
     Remove-AzStorageContainer -Name (-join($containerPrefix, $i)) -Context $ctx
    } 

# Retrieve container list, delete using a pipeline
 Get-AzStorageContainer -Prefix $prefixName -Context $ctx | Remove-AzStorageContainer

在某些情况下,可以检索已删除的容器。 如果已启用存储帐户的软删除数据保护选项,-IncludeDeleted 参数将返回在关联保留期内删除的容器。 在返回容器列表时,-IncludeDeleted 参数只能与 -Prefix 参数结合使用。 若要详细了解软删除,请参阅容器软删除一文。

使用以下示例检索在存储帐户的关联保留期内删除的容器列表。

# Retrieve a list of containers including those recently deleted
 Get-AzStorageContainer -Prefix $prefixName -Context $ctx -IncludeDeleted

还原软删除的容器

列出容器部分中所述,可以对存储帐户配置软删除数据保护选项。 启用后,可以还原在关联保持期内删除的容器。

以下示例说明如何使用 Restore-AzStorageContainer cmdlet 还原已软删除的容器。 你需要启用软删除,并在至少一个存储帐户上配置它,然后才能按照此示例操作。

若要详细了解软删除数据保护选项,请参阅容器软删除一文。

# Create variables
 $accountName = "<storage-account>"
 $prefixName  = "loop-"

# Create a context object using Azure AD credentials
 $ctx = New-AzStorageContext -StorageAccountName $accountName -UseConnectedAccount

# Retrieve all containers, filter deleted containers, restore deleted containers
 Get-AzStorageContainer -Prefix $prefixName -IncludeDeleted `
    -Context $ctx | ? { $_.IsDeleted } | Restore-AzStorageContainer

结果将显示已还原的所有带 demo 前缀的容器。

    Storage Account Name: demostorageaccount

Name                 PublicAccess         LastModified                   IsDeleted  VersionId        
----                 ------------         ------------                   ---------  ---------        
loop-container3                                                                                       
loop-container4               

另请参阅