本示例将所有 blob 对象从用户提供的源存储帐户迁移到用户提供的目标存储帐户。
此操作通过使用 Get-AzStorageContainer
命令实现,该命令将列出存储帐户中的所有容器。 然后,示例发出 AzCopy 命令,将每个容器从源存储帐户复制到目标存储帐户。 如果失败,示例将重试 $retryTimes 次(默认为 3,可通过 -RetryTimes
参数修改)。 如果每次重试都失败,用户可重新运行脚本,并使用 -LastSuccessContainerName
参数向示例提供上次成功复制的容器。 然后,示例将继续从该点复制容器。
本示例需要 Azure PowerShell 存储模块 0.7 或更高版本。 可使用 Get-Module -ListAvailable Az.storage
检查安装的版本。 如果需要进行安装或升级,请参阅安装 Azure PowerShell 模块。
如果还没有 Azure 订阅,可以在开始前创建一个免费帐户。
本示例需要最新版本的 Windows 版 AzCopy。 默认安装目录为 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 文档。
有关其他存储 PowerShell 脚本示例,可参阅 Azure Blob 存储的 PowerShell 示例。