在 Windows 上使用 AzCopy 在儲存體帳戶間移轉 blob
這個範例會將所有 blob 物件從使用者提供的來源儲存體帳戶,複製到使用者提供的目標儲存體帳戶。
這是藉由使用 Get-AzStorageContainer
命令來完成,該命令會列出儲存體帳戶中的所有容器。 此範例接著會發出 AzCopy 命令,將每個容器從來源儲存體帳戶複製到目的地儲存體帳戶。 如果發生任何失敗,此範例會重試 $retryTimes 次 (預設值為 3,而且可以使用 -RetryTimes
參數修改)。 如果每次重試都發生失敗,使用者可以重新執行指令碼,方法是使用 -LastSuccessContainerName
參數,提供具有最後成功複製容器的範例。 此範例接著會繼續從該點複製容器。
此範例需要 Azure PowerShell 儲存體模組 0.7 版或更新版本。 您可以使用 Get-Module -ListAvailable Az.storage
檢查已安裝的版本。 如果您需要安裝或升級,請參閱安裝 Azure PowerShell 模組。
如果您沒有 Azure 訂用帳戶,請在開始前建立免費帳戶。
此範例也需要最新版本的 AzCopy on Windows。 預設安裝目錄是 C:\Program Files (x86)\Microsoft SDKs\Azure\AzCopy\
這個範例會採用來源儲存體帳戶名稱和金鑰、目標儲存體帳戶名稱和金鑰,以及 AzCopy.exe 的完整檔案路徑 (如果它不是安裝在預設目錄)。
此範例的輸入範例如下:
如果 AzCopy 是安裝在預設目錄:
srcStorageAccountName: ExampleSourceStorageAccountName
srcStorageAccountKey: ExampleSourceStorageAccountKey
DestStorageAccountName: ExampleTargetStorageAccountName
DestStorageAccountKey: ExampleTargetStorageAccountKey
如果 AzCopy 不是安裝在預設目錄:
srcStorageAccountName: ExampleSourceStorageAccountName
srcStorageAccountKey: ExampleSourceStorageAccountKey
DestStorageAccountName: ExampleTargetStorageAccountName
DestStorageAccountKey: ExampleTargetStorageAccountKey
AzCopyPath: C:\Program Files (x86)\Microsoft SDKs\Azure\AzCopy\AzCopy.exe
如果發生失敗,而且範例必須從特定的容器重新執行:
.\copyScript.ps1 -LastSuccessContainerName myContainerName
範例指令碼
# Run the script in a new open Powershell window, which has not run other cmdlets, or AzCopy performance could suffer .
# Need install Azure PowerShell before runing the script: https://github.com/Azure/azure-powershell/releases
# Need install AzCopy before runing the script: https://docs.microsoft.com/Az.Storage/common/storage-use-azcopy
# Do not modify the Source or Destination accounts while the copy is running
param (
[Parameter(Mandatory = $true,
HelpMessage= "Source Storage account name.")]
[ValidatePattern("^[a-z0-9`]{3,24}$")]
[String]$srcStorageAccountName,
[Parameter(Mandatory = $true,
HelpMessage= "Source Storage account key.")]
[String]$srcStorageAccountKey,
[Parameter(Mandatory = $true,
HelpMessage= "Destination Storage account name.")]
[ValidatePattern("^[a-z0-9`]{3,24}$")]
[String]$DestStorageAccountName,
[Parameter(Mandatory = $true,
HelpMessage= "Destination Storage account key.")]
[String]$DestStorageAccountKey,
[Parameter(Mandatory = $false,
HelpMessage= "Input the full filePath of the AzCopy.exe, e.g.: C:\Program Files (x86)\Microsoft SDKs\Azure\AzCopy\AzCopy.exe")]
[String]$AzCopyPath = "C:\Program Files (x86)\Microsoft SDKs\Azure\AzCopy\AzCopy.exe",
[Parameter(Mandatory = $false,
HelpMessage='Sets the number of retries in an event of failure. Set to 0 for no retry, set -1 for infinite retry.')]
[Int32]$RetryTimes = 3,
[Parameter(Mandatory = $false,
ValueFromPipeline = $true,
HelpMessage='Used for resume operation. When provided, the script will copy containers that are alphabetically after $LastSuccessContainerName')]
[String]$LastSuccessContainerName = $nullz
)
if( (Get-Item $AzCopyPath).Exists)
{
$FileItemVersion = (Get-Item $AzCopyPath).VersionInfo
$FilePath = ("{0}.{1}.{2}.{3}" -f $FileItemVersion.FileMajorPart, $FileItemVersion.FileMinorPart, $FileItemVersion.FileBuildPart, $FileItemVersion.FilePrivatePart)
# only netcore version AzCopy.exe has version 0.0.0.0, and all netcore version AzCopy works in this script
if(([version] $FilePath -lt "7.0.0.2") -and ([version] $FilePath -ne "0.0.0.0"))
{
$AzCopyPath = Read-Host "Version of AzCopy found at default install directory is of a lower, unsupported version. Please input the full filePath of the AzCopy.exe that is version 7.0.0.2 or higher, e.g.: C:\Program Files (x86)\Microsoft SDKs\Azure\AzCopy\AzCopy.exe"
}
}
elseIf( (Get-Item $AzCopyPath).Exists -eq $false)
{
$AzCopyPath = Read-Host "Input the full filePath of the AzCopy.exe, e.g.: C:\Program Files (x86)\Microsoft SDKs\Azure\AzCopy\AzCopy.exe"
}
# Create and check Storage context
$Error.Clear()
$srcCtx = New-AzStorageContext -StorageAccountName $srcStorageAccountName -StorageAccountKey $srcStorageAccountKey
if ($srcCtx -eq $null)
{
Write-Error "Script could not create source Storage Context, possibly due to invalid StorageAccountName or StorageAccount Key terminating: $Error[0]";
return;
}
$destCtx = New-AzStorageContext -StorageAccountName $destStorageAccountName -StorageAccountKey $destStorageAccountKey
if ($destCtx -eq $null)
{
Write-Error "Script could not create destination storage context, possibly due to invalid StorageAccountName or StorageAccount Key terminating: $Error[0]";
return;
}
#Check Source and Destination Storage account Connection
$Error.Clear()
$Containers = Get-AzStorageContainer -MaxCount 1 -Context $srcCtx
if ($Error.Count -gt 0)
{
Write-Error "Script failed to connect to source Storage account, terminating: $Error[0]";
return;
}
$Containers = Get-AzStorageContainer -MaxCount 1 -Context $destCtx
if ($Error.Count -gt 0)
{
Write-Error "Script failed to connect to destination Storage account, terminating: $Error[0]";
return;
}
#Check AzCopy Path
if((Test-Path $AzCopyPath) -eq $false)
{
Write-Error "Script is terminating since the provided AzCopyPath does not exist: $AzCopyPath ";
return;
}
elseif((Get-Item $AzCopyPath).BaseName -ne "AzCopy" )
{
Write-Error "Script is terminating since the provided AzCopyPath does not refer to the AzCopy exe: $AzCopyPath ";
return;
}
elseif((Get-Item $AzCopyPath).BaseName -eq "AzCopy")
{
$FileItemVersion = (Get-Item $AzCopyPath).VersionInfo
$FilePath = ("{0}.{1}.{2}.{3}" -f $FileItemVersion.FileMajorPart, $FileItemVersion.FileMinorPart, $FileItemVersion.FileBuildPart, $FileItemVersion.FilePrivatePart)
if([version] $FilePath -lt "7.0.0.2")
{
$AzCopyPath = Read-Host "Version of AzCopy found at provided path is of a lower, unsupported version. Please input the full filePath of the AzCopy.exe that is version 7.0.0.2 or higher, e.g.: C:\Program Files (x86)\Microsoft SDKs\Azure\AzCopy\AzCopy.exe"
}
}
$OutputLastSuccessContainer = $LastSuccessContainerName;
$HasReachedLastSuccessContainer = $false;
if ($LastSuccessContainerName -eq $null -or $LastSuccessContainerName -eq "")
{
$HasReachedLastSuccessContainer = $true;
}
# For list container
$MaxReturn = 250
$Token = $Null
do{
# List source containers
$retry = 1
$Error.Clear()
$srcContainers = Get-AzStorageContainer -MaxCount $MaxReturn -ContinuationToken $Token -Context $srcCtx
# If list container fail, retry it
while(($Error.Count -gt 0) -and ($RetryTimes -eq -1 -or $retry -le $retryTimes))
{
Write-Host "Retry List containers $retry"
$Error.Clear()
$srcContainers = Get-AzStorageContainer -MaxCount $MaxReturn -ContinuationToken $Token -Context $srcCtx
$retry++
}
# If list container fail after retry, break script
if ($Error.Count -gt 0){
Write-Error "Terminating the script since listing source containers failed: $Error[0]";
$CopyContainerFail = $true
break;
}
$Token = $srcContainers[$srcContainers.Count -1].ContinuationToken;
# Transfer containers one by one
$CopyContainerFail = $false
foreach ($container in $srcContainers)
{
if (!$HasReachedLastSuccessContainer)
{
if ($container.Name -eq $LastSuccessContainerName)
{
$HasReachedLastSuccessContainer = $true;
}
Write-Host "Skipping container copy: $($container.Name)"
Continue;
}
Write-Host "Start copying container: $($container.Name)"
$retry = 1
# Get AzCopy command for transfer one container
$destContainer = $destCtx.StorageAccount.CreateCloudBlobClient().GetContainerReference($container.Name)
$azCopyCmd = [string]::Format("""{0}"" /source:{1} /dest:{2} /sourcekey:""{3}"" /destkey:""{4}"" /snapshot /y /s /synccopy",$AzCopyPath, $container.CloudBlobContainer.Uri.AbsoluteUri, $destContainer.Uri.AbsoluteUri, $srcStorageAccountKey, $DestStorageAccountKey)
# Execute the AzCopy command first time
Write-Host "$azCopyCmd"
$result = cmd /c $azCopyCmd
foreach($s in $result)
{
Write-Host $s
}
# If transfer failed, retry it
while(($LASTEXITCODE -ne 0) -and ($RetryTimes -eq -1 -or $retry -le $retryTimes))
{
Write-Host "Retry $retry : $azCopyCmd"
$result = cmd /c $azCopyCmd
foreach($s in $result)
{
Write-Host $s
}
$retry++
}
# If tranfer failed after retry, print error
if ($LASTEXITCODE -ne 0){
Write-Error "Container copy failed: $($container.Name)";
$CopyContainerFail = $true
break;
}
else
{
Write-Host "Finished copying container: $($container.Name)"
Write-Host ""
$OutputLastSuccessContainer = $container.Name
}
}
if($CopyContainerFail)
{
break;
}
}
While ($Token -ne $Null)
# Summary the copy result
if ($CopyContainerFail)
{
if(($OutputLastSuccessContainer -ne $null) -and ($OutputLastSuccessContainer -ne ""))
{
Write-Warning "To resume, rerun the script and append the parameter: ""-LastSuccessContainer $OutputLastSuccessContainer"""
return $OutputLastSuccessContainer
}
else
{
Write-Warning "To resume, rerun the script."
return $null
}
}
else
{
Write-Host "All Containers copied successfully."
return ""
}
指令碼說明
此指令碼會使用下列命令,將資料從一個儲存體帳戶複製到另一個。 下表中的每個項目都會連結至特定命令的文件。
Command | 注意 |
---|---|
Get-AzStorageContainer | 傳回與儲存體帳戶關聯的容器。 |
New-AzStorageContext | 建立 Azure 儲存體內容。 |
後續步驟
如需有關 Azure PowerShell 模組的詳細資訊,請參閱 Azure PowerShell 文件。
在 Azure Blob 儲存體的 PowerShell 範例中,提供了其他儲存體 PowerShell 指令碼範例。