zoukankan      html  css  js  c++  java
  • PowerShell 操作 Azure Blob Storage

    本文假设已经存在了一个 Azure Storage Account,需要进行文件的上传,下载,复制,删除等操作。
    为了方便查看 PowerShell 代码执行的结果,本文使用了 MS 发布的一个 Azure Storage 客户端工具:Microsoft Azure Storage Explorer,文中简称为 Storage Explorer。

    安装 PowerShell Azure 模块

    操作 Azure 的模块是不随 PowerShell 一起安装的,使用前需要单独的安装。

    PowerShellGet 模块
    如果要从 PowerShell Gallery 安装 Azure 模块,需要确保已经安装了 PowerShellGet 模块。下面的命令检查已安装 PowerShellGet 模块的版本:

    Get-Module PowerShellGet -list | Select-Object Name,Version,Path

    安装 Azure PowerShell 模块
    下面的命令安装 Azure Resource Manager 模块:

    Install-Module AzureRM -AllowClobber

    注意,安装过程中有确认安装的交互过程。

    载入 Azure 模块
    在使用 Azure 相关的命令前需要通过 Import-Module 命令加载 Azure 模块:

    Import-Module AzureRM

    创建 Azure Storage 上下文

    如果我们要对一个 Storage Account 中的文件进行操作,需要提供访问 Storage Account 的认证信息。我们的方式是直接通过 New-AzureStorageContext 命令创建一个 AzureStorageContext 类型的对象,这个对象中包含了认证信息,所以接下来所有对 storage 的访问操作都需要使用它:

    $ctx = New-AzureStorageContext -ConnectionString "DefaultEndpointsProtocol=https;AccountName=youraccountname;AccountKey=youraccesskey;"

    除了使用 -ConnectionString 选项,还可以把参数分开来写:

    $StorageAccountName = "youraccountname"
    $StorageAccountKey = "youraccesskey"
    $ctx = New-AzureStorageContext -StorageAccountName $StorageAccountName -StorageAccountKey $StorageAccountKey -Protocol Https

    注意,在上面的命令中除了添加必要的认证选项外,我们还显式的指定了通信协议。指定 https 是非常重要的,因为以 https 协议上传下载的数据默认会进行数据的完整性校验。也就是说在进行文件的上传或者下载时,我们不需要再做额外的数据完整性校验了。

    除了 New-AzureStorageContext 命令,还有其他的方式可以获得 AzureStorageContext 对象。比如可以先通过 Login-AzureRmAccount 登录,然后找到某个(或者是创建一个) Storage Account,并获取其 Context 属性。

    创建 Container

    任何的 blob 对象都必须被包含在一个 Container 中,所以在进行 blob 文件的操作前,我们需要先创建一个 Container:

    $ContainerName = "containertest"
    New-AzureStorageContainer -Name $ContainerName -Permission Off -Context $ctx

    为 Container 设置的权限会控制 Container 中的所有文件,当前一共有三个权限类型:
    Container:匿名用户可以访问文件内容,并且可以枚举 Container 中的所有文件。
    Blob:匿名用户可以访问文件内容,但是不能枚举 container 中的文件。
    Off:匿名用户不能访问文件。
    -Permission 选项用来设置 Container 的权限,默认值是 Off(笔者喜欢总是显式的指定这个选项以提高脚本的可读性)。
    -Context 选项指定该命令的执行上下文,主要是认证信息,这里我们使用前面生成的对象 $ctx。

    上传文件

    我们可以通过 Set-AzureStorageBlobContent 命令来上传文件,需要指定文件存放的 Container 和 访问 Storage Account 的上下文:

    Set-AzureStorageBlobContent -Container $ContainerName -File ".cortana.jpg" -Blob "cortana.jpg" -Context $ctx

    上传成功后我们可以通过 Storage Explorer 直观的检查一下:

    这样上传的文件都是直接放在 Container 的根目录下的,如果要对文件存放的目录进行管理,需要在上传时指定包含目录名称的文件名:

    Set-AzureStorageBlobContent -Container $ContainerName -File ".cortana.jpg" -Blob "images/cortana.jpg" -Context $ctx

    这样上传后,文件 cortana.jpg 会存放在 images 目录下。

    上传目录下的多个文件
    我们还可以通过一个命令一次上传某个目录下的所有文件:

    Get-ChildItem -Path "D:ConsoleApplication1" -File -Recurse | Set-AzureStorageBlobContent -Container $ContainerName -Context $ctx

    D:ConsoleApplication1 目录中是一个简单的 C# 控制台应用,通过管道组合 Get-ChildItem 命令,可以完成多个文件的上传,并且这些文件的目录结构和原来都是一样的。

    覆盖已经存在的 blob
    如果我们要上传一个文件,并指定了一个已经存在的 blob 名称,此时会与用户交互以确定是否覆盖已经存在的 blob。对于各种自动化的任务,我们不希望交互的行为,所以可以加上 -Force 选项强制覆盖已有文件:

    Set-AzureStorageBlobContent -Container $ContainerName -File ".cortana.jpg" -Blob "cortana.jpg" -Context $ctx -Force

    下载文件

    Get-AzureStorageBlobContent 命令用来下载文件。下载文件的前提是你知道某个 blob 对象的名称:

    $localFileDirectory = "D:"
    Get-AzureStorageBlobContent -Destination $localFileDirectory -Container $ContainerName -Blob "images/cortana.jpg" -Context $ctx -Force

    注意,下载到本地的文件路径为:"D:imagescortana.jpg"。

    其实在很多的情况下我们都没有这么明确的 blob 名称,我们需要下载满足某些情况的 blob,比如下载 images 目录下的所有文件。这里的问题是我们不知道 images 究竟是哪级目录,所以可能的做法是遍历 Container 下的所有文件,然后检查文件名称中包含 images 目录的文件并下载它。为了遍历 Container 中的文件,需要使用 Get-AzureStorageBlob 命令:

    $localFileDirectory = "D:"
    $blobs = Get-AzureStorageBlob -Container $ContainerName -Context $ctx
    foreach($blob in $blobs)
    {
        if($blob.Name.Contains("images/"))
        {
            Get-AzureStorageBlobContent -Destination $localFileDirectory -Container $ContainerName -Blob $blob.Name -Context $ctx -Force
        }
    }

    这段代码中我们用 Get-AzureStorageBlob 命令拿到 Container 下的所有文件信息,然后检查文件的路径中有没有包含 "images/" 字符串,如果包含,就下载这个文件。

    复制文件

    自动化的脚本操作可以轻松愉快的备份各种数据,当然也包含存储在 Storage Account 中的文件。Start-AzureStorageBlobCopy 命令用于 blob 文件的复制操作。单从名字上看这应该是个异步方法,但是真实的情况稍微复杂一些。因为这个命令既可以用于同步操作也可以用于异步操作,关键在于调用这个命令的方式!下面的命令在同一个 Container 中执行文件复制操作:

    Start-AzureStorageBlobCopy -SrcBlob "cortana.jpg" `
                               -SrcContainer $ContainerName `
                               -DestContainer $ContainerName `
                               -DestBlob "myimages/cortana.jpg" `
                               -Context $ctx

    这个操作是同步执行的,它把 Container 根目录下的 cortana.jpg 文件拷贝到同一个 Container 的 myimages 目录下。

    如果你要跨地域的在不同的 Storage Account 中复制大量的文件,建议你通过异步的方式进行:

    # 把 Start-AzureStorageBlobCopy 命令的返回值存储到变量中会让复制过程以异步的方式进行。
    $blobResult = Start-AzureStorageBlobCopy -SrcBlob $blobName `
      -SrcContainer $containerName `
      -DestContainer $containerName2 `
      -DestBlob $blobName `
      -Context $ctx `
      -DestContext $ctx2
    # 然后通过检查返回值的方式确定复制操作是否完成。
    $status = $blobResult | Get-AzureStorageBlobCopyState
    # 通过循环,当检查到结果的状态不为 "Pending" 时,表示复制操作已经完成。
    while ($status.Status -eq "Pending") {
        $status = $blobResult | Get-AzureStorageBlobCopyState
        $status
        Start-Sleep 10
    }

    删除文件

    Remove-AzureStorageBlob 命令删除指定的 blob 文件:

    Remove-AzureStorageBlob -Container $ContainerName -Blob "myimages/cortana.jpg" -Context $ctx

    要是有复杂点的要求,就得通过遍历 Contaner 中的文件来完成。

    权限管理

    在创建 Container 时我们已经提到,可以给 Container 设置三种不同的访问控制权限:Container,Blob,Off。我们也可以在创建 Container 之后通过 Set-AzureStorageContainerAcl 命令改变它的访问控制权限。下面的命令把 Container 的访问控制权限设置为 Blob:

    Set-AzureStorageContainerAcl -Name $containerName -Context $ctx -Permission Blob
  • 相关阅读:
    总结:使用pll来进行“异步复位,同步释放”
    总结“异步复位,同步释放”
    用quartusII再带的modelsim进行后仿真(时序仿真)的操作步骤
    Notepad++新建文件默认保存格式修改问题
    英语翻译正确的思维
    浅谈web网站架构演变过程
    MVC-API(二)
    C#面向对象编程的基础
    C# 堆栈讲解
    AutoCAD 2013 之R14版本下载地址整理汇总
  • 原文地址:https://www.cnblogs.com/sparkdev/p/7853138.html
Copyright © 2011-2022 走看看