【发布时间】:2015-10-22 23:53:53
【问题描述】:
我有两个 Azure 存储帐户。在其中一个存储帐户上,有近 100 个容器和这些容器中的一些 blob。我想将所有这些容器连同其中的 blob 一起转移到其他存储帐户。
我见过许多工具将 blob 从一个容器复制到另一个容器,但没有遇到任何复制整个容器的工具。请帮忙。
谢谢
【问题讨论】:
标签: azure-storage
我有两个 Azure 存储帐户。在其中一个存储帐户上,有近 100 个容器和这些容器中的一些 blob。我想将所有这些容器连同其中的 blob 一起转移到其他存储帐户。
我见过许多工具将 blob 从一个容器复制到另一个容器,但没有遇到任何复制整个容器的工具。请帮忙。
谢谢
【问题讨论】:
标签: azure-storage
有点晚了,但这个 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,并添加了循环容器的代码,而不是手动指定它们。
【讨论】:
您可以尝试以下基于 Azcopy 的脚本。 它将列出一个存储帐户中的所有容器,并通过 AzCopy 将它们一一复制到另一个存储帐户。
复制一切
使用 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
【讨论】:
我在计划的 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
}
}
【讨论】:
这是从 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"
}
【讨论】:
与上述类似,但将 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
【讨论】:
我强烈建议您查看 Azure 存储资源管理器 https://azure.microsoft.com/en-us/features/storage-explorer/。它比 azcopy 容易得多,甚至可以在容器之间复制和粘贴。
【讨论】:
你看到这个工具了吗?:https://azure.microsoft.com/en-us/documentation/articles/storage-use-azcopy/,它可以将所有 blob 从一个容器复制到另一个容器。
但是,当我需要在帐户之间移动内容时,我最终将所有内容下载到 VM,然后将其上传回新帐户。
【讨论】: