【问题标题】:How to Copy All Containers along with Blobs from one Azure storage account to other storage account如何将所有容器和 Blob 从一个 Azure 存储帐户复制到另一个存储帐户
【发布时间】:2015-10-22 23:53:53
【问题描述】:

我有两个 Azure 存储帐户。在其中一个存储帐户上,有近 100 个容器和这些容器中的一些 blob。我想将所有这些容器连同其中的 blob 一起转移到其他存储帐户。

我见过许多工具将 blob 从一个容器复制到另一个容器,但没有遇到任何复制整个容器的工具。请帮忙。

谢谢

【问题讨论】:

    标签: azure-storage


    【解决方案1】:

    有点晚了,但这个 PowerShell 脚本会做到的......

    #Server side storage copy
    $SourceStorageAccount = "sourceAccountName"
    $SourceStorageKey = "sourceAccountAPIKey"
    $DestStorageAccount = "destinationAccountName"
    $DestStorageKey = "destinationAccountAPIKey"
    $SourceStorageContext = New-AzureStorageContext -StorageAccountName $SourceStorageAccount -StorageAccountKey $SourceStorageKey
    $DestStorageContext = New-AzureStorageContext -StorageAccountName $DestStorageAccount -StorageAccountKey $DestStorageKey
    
    $Containers = Get-AzureStorageContainer -Context $SourceStorageContext
    
    foreach($Container in $Containers)
    {
        $ContainerName = $Container.Name
        if (!((Get-AzureStorageContainer -Context $DestStorageContext) | Where-Object { $_.Name -eq $ContainerName }))
        {   
            Write-Output "Creating new container $ContainerName"
            New-AzureStorageContainer -Name $ContainerName -Permission Off -Context $DestStorageContext -ErrorAction Stop
        }
    
        $Blobs = Get-AzureStorageBlob -Context $SourceStorageContext -Container $ContainerName
        $BlobCpyAry = @() #Create array of objects
    
        #Do the copy of everything
        foreach ($Blob in $Blobs)
        {
           $BlobName = $Blob.Name
           Write-Output "Copying $BlobName from $ContainerName"
           $BlobCopy = Start-CopyAzureStorageBlob -Context $SourceStorageContext -SrcContainer $ContainerName -SrcBlob $BlobName -DestContext $DestStorageContext -DestContainer $ContainerName -DestBlob $BlobName
           $BlobCpyAry += $BlobCopy
        }
    
        #Check Status
        foreach ($BlobCopy in $BlobCpyAry)
        {
           #Could ignore all rest and just run $BlobCopy | Get-AzureStorageBlobCopyState but I prefer output with % copied
           $CopyState = $BlobCopy | Get-AzureStorageBlobCopyState
           $Message = $CopyState.Source.AbsolutePath + " " + $CopyState.Status + " {0:N2}%" -f (($CopyState.BytesCopied/$CopyState.TotalBytes)*100) 
           Write-Output $Message
        }
    }
    

    该脚本的一些功劳归功于这篇博文...

    http://windowsitpro.com/azure/copy-content-one-azure-storage-account-another

    ...我修改了他的代码,删除了讨厌的 long dashes,并添加了循环容器的代码,而不是手动指定它们。

    【讨论】:

    • 脚本是否要在所有副本完成之前结束?另请注意,除法(在“检查状态”循环内)可能会导致“除零”错误。此外,答案中的第一个链接已损坏。
    • @Tom 真的!但前提是没有要复制的字节。您可以删除这两行...它们只是提供信息。或者你可以写一个 if 语句
    【解决方案2】:

    您可以尝试以下基于 Azcopy 的脚本。 它将列出一个存储帐户中的所有容器,并通过 AzCopy 将它们一一复制到另一个存储帐户。

    https://docs.microsoft.com/en-us/azure/storage/scripts/storage-common-transfer-between-storage-accounts

    复制一切

    使用 azcopy copy 命令将所有容器、目录和 Blob 复制到另一个存储帐户。

    azcopy copy 'https://<source-storage-account-name>.blob.core.windows.net/<SAS-token>' 'https://<destination-storage-account-name>.blob.core.windows.net/' --recursive
    
    azcopy copy 'https://mysourceaccount.blob.core.windows.net/?sv=2018-03-28&ss=bfqt&srt=sco&sp=rwdlacup&se=2019-07-04T05:30:08Z&st=2019-07-03T21:30:08Z&spr=https&sig=CAfhgnc9gdGktvB=ska7bAiqIddM845yiyFwdMH481QA8%3D' 'https://mydestinationaccount.blob.core.windows.net' --recursive
    

    source

    【讨论】:

    • 如果您有更多容器和/或 blob,则可以手动管理,这是最好的答案。与其他 PowerShell 脚本答案不同,AzCopy 还将并行批处理文件副本,这在我的案例中导致了 10 倍的性能提升。此外,如果您不知道(我不知道),您可以从 Azure 门户轻松获取所需的 SAS 令牌。
    【解决方案3】:

    我在计划的 Azure 自动化 Runbook 作业中使用 Mick's script 来备份 Blob 存储。

    在尝试复制之前,我对其进行了这个小改动,以检查目标容器中是否已经存在 blob:

    #Do the copy of everything
    foreach ($Blob in $Blobs)
    {
       $BlobName = $Blob.Name
       $blob = Get-AzureStorageBlob -Blob $BlobName -Container $ContainerName -Context 
       $DestStorageContext -ErrorAction Ignore
       if (-not $blob)
       {
          Write-Output "Copying $BlobName from $ContainerName"
          $BlobCopy = Start-CopyAzureStorageBlob -Context $SourceStorageContext -SrcContainer $ContainerName -SrcBlob $BlobName -DestContext $DestStorageContext -DestContainer $ContainerName -DestBlob $BlobName
          $BlobCpyAry += $BlobCopy
       }  
    } 
    

    【讨论】:

    • 您应该实际显示已完成的代码以及您的更改。这对人们更有帮助。
    【解决方案4】:

    这是从 2020 年开始的,归功于 @Mick。我刚刚删除了单独的 blob 副本。它会在一行中覆盖整个容器。如果代码执行,则保证可以正常工作。所以没有检查。 注意:这不会复制文件夹,而是提供error

    #Server side storage copy
    $SourceStorageAccount = "sourceAccountName"
    $SourceStorageKey = "sourceAccountAPIKey"
    $DestStorageAccount = "destinationAccountName"
    $DestStorageKey = "destinationAccountAPIKey"
    $SourceStorageContext = New-AzureStorageContext -StorageAccountName $SourceStorageAccount -StorageAccountKey $SourceStorageKey
    $DestStorageContext = New-AzureStorageContext -StorageAccountName $DestStorageAccount -StorageAccountKey $DestStorageKey
    
    $Containers = Get-AzureStorageContainer -Context $SourceStorageContext
    
        foreach($Container in $Containers)
    {
        $ContainerName = $Container.Name
        if (!((Get-AzureStorageContainer -Context $DestStorageContext) | Where-Object { $_.Name -eq $ContainerName }))
        {   
            Write-Output "Creating new container $ContainerName"
            New-AzureStorageContainer -Name $ContainerName -Permission Off -Context $DestStorageContext -ErrorAction Stop
        }
        Write-Output "start copy $ContainerName"
        az storage blob copy start-batch --destination-container "$ContainerName" --account-name "$DestStorageAccount" --account-key "$DestStorageKey" --source-account-name "$SourceStorageAccount" --source-account-key "$SourceStorageKey" --source-container "$ContainerName"
    }
    

    【讨论】:

      【解决方案5】:

      与上述类似,但将 Bash 与 Azure CLI 和 AZCopy 结合使用 - 代码在 Github 上,相关视频在 YouTube 上。

      https://github.com/J0hnniemac/yt-blobsync

      #!/bin/bash
      cd /home
      app_id=""
      tenant=""
      sourceurl="https://<>.blob.core.windows.net"
      destinationurl="https://<>.blob.core.windows.net"
      
      pemfile="/home/service-principal.pem"
      
      sourceaccount=$(echo $sourceurl | awk -F/ '{print $3}' | awk -F. '{print $1}')
      destinationaccount=$(echo $destinationurl | awk -F/ '{print $3}' | awk -F. '{print $1}')
      
      echo $app_id
      echo $tenant
      echo $sourceurl
      echo $destinationurl
      
      echo $sourceaccount
      echo $destinationaccount
      
      az login --service-principal --password $pemfile --username $app_id --tenant $tenant
      
      # list storage containers
      az storage container list --auth-mode login --account-name $sourceaccount -o=table | awk 'NR>1 {print $1}' | grep networking-guru > src.txt
      az storage container list --auth-mode login --account-name $destinationaccount -o=table | awk 'NR>1 {print $1}' | grep networking-guru > dst.txt
      
      grep -vf dst.txt src.txt > diff.txt 
      
      for blob_container in $(cat diff.txt);
              do
              echo $blob_container;
              newcmd="az storage container create --auth-mode login --account-name $destinationaccount -n $blob_container --fail-on-exist" 
              echo "---------------------------------"
              echo $newcmd
              eval $newcmd
      done
      
      echo "performing AZCOPY login"
      azcopy login --service-principal --certificate-path $pemfile --application-id $app_id --tenant-id $tenant
      
      
      
      echo "performing AZCOPY sync for each container"
      for blob_container in $(cat src.txt);
         do
          #Create timestame + 30 Minutes for SAS token
          end=`date -u -d "30 minutes" '+%Y-%m-%dT%H:%MZ'`
          sourcesas=`az storage container generate-sas --account-name $sourceaccount --as-user --auth-mode login --name $blob_container --expiry $end --permissions acdlrw`
          echo $sourcesas
          # remove leading and trailing quotes from SAS Token
          sourcesas=$(eval echo $sourcesas)
          echo $sourcesas
          src="$sourceurl/$blob_container?$sourcesas"
          dst="$destinationurl/$blob_container"
          echo $src
          echo $dst
          synccmd="azcopy sync \"$src\" \"$dst\" --recursive --delete-destination=true"
          echo $synccmd
          eval $synccmd
      done
      

      【讨论】:

        【解决方案6】:

        我强烈建议您查看 Azure 存储资源管理器 https://azure.microsoft.com/en-us/features/storage-explorer/。它比 azcopy 容易得多,甚至可以在容器之间复制和粘贴。

        【讨论】:

          【解决方案7】:

          你看到这个工具了吗?:https://azure.microsoft.com/en-us/documentation/articles/storage-use-azcopy/,它可以将所有 blob 从一个容器复制到另一个容器。

          但是,当我需要在帐户之间移动内容时,我最终将所有内容下载到 VM,然后将其上传回新帐户。

          【讨论】:

          • 我想将我拥有的 100 个容器从一个帐户复制到另一个帐户。复制块可以使用许多可用的工具来完成,想知道如何复制容器本身。
          • @CourageousHeart,无法复制容器。您必须自己创建目标容器:手动或以编程方式。工具只能遍历容器内的 blob 并一一复制。
          • 目前我有大约 100 个容器,不确定手动创建它们是否正确。惊讶地发现没有工具也可以复制容器:(
          • 您可以创建一个powershell脚本,使用Azure storage PSH cmdlet迭代所有容器,并使用PSH cmdlet调用AzCopy exe复制每个容器。
          猜你喜欢
          • 2021-08-25
          • 2023-04-06
          • 1970-01-01
          • 2021-06-27
          • 2021-12-23
          • 1970-01-01
          • 1970-01-01
          • 2018-03-30
          • 2016-11-25
          相关资源
          最近更新 更多