info@techdevops.com | 437-991-3573 | Data Engineering Services
TechDevOps.com
Resources Tools
Experts in Microsoft SQL Server on Windows, Linux, Containers | Clusters, Always On, FCI | Migrations, Cloud, Performance



Microsoft Azure - copy all content from one storage container to another
by BF (Principal Consultant; Architecture; Engineering)
2017-03-26









The below Powershell code will copy all the content, or a single file, from one Azure Storage Subscription/Account to another Storage Subscription/Account. Variables exists to copy all files or a single file, whether to clear the destination container & whether to input a delay prior to checking the copy status. The main Powershell cmdlets are Get-AzureStorageBlob, Start-CopyAzureStorageBlob & Get-AzureStorageBlobCopyState.



Powershell Code:


#Authenticate to Microsoft Azure:
#Login-AzureRmAccount

#Clear Prior Output:
cls

#Declare Variables:
#Leave as empty quotes to copy all files in a container
$CopySpecificFileName = "" #"Troubleshooting and Optimizing Queries with SQL Azure.docx"

#Set to 1 to delete all contents in the destination container prior to copy command starting:
$ClearDestContainer = 1

#Set a time in sec to delay/wait before checking on copy status:
$WaitBeforeCheckingCopyStatus = 30

#Set Variables:
$SrcStgAcc = "xyzacc"
$DestStgAcc = "xyzacc"
$SrcStgAccKey = "xyz=="
$DestStgKey = "xyz=="
$SrcStgContainer = 'src01'
$DestStgContainer = 'dest01'

#Get Azure Storage Context(s):
$SrcStgContext = New-AzureStorageContext –StorageAccountName $SrcStgAcc -StorageAccountKey $SrcStgAccKey
$DestStgContext = New-AzureStorageContext –StorageAccountName $DestStgAcc -StorageAccountKey $DestStgKey

#Delete all contents of the destination container if $ClearDestContainer = 1:
If ($ClearDestContainer -eq 1)
{
Write-Host "[Deleting]:" $DestStgAcc": "$SrcStgContainer "- all destination container contents being removed"
$BlobDest = Get-AzureStorageBlob -Context $DestStgContext -Container $DestStgContainer
Get-AzureStorageBlob -Container $DestStgContainer -Context $DestStgContext | ForEach-Object {Remove-AzureStorageBlob -Blob $_.Name -Container $DestStgContainer -Context $DestStgContext}
Write-Host " "
}

#Get Azure Source Blob Object:
$Blobs = Get-AzureStorageBlob -Context $SrcStgContext -Container $SrcStgContainer

#Declare an array to store results of copy cmdlet to use in check copy:
$BlobCopyArray = @()

#Start Files(s) Copy:
If([string]::IsNullOrEmpty($CopySpecificFileName))
{
#Copy all container contents:
foreach ($Blob in $Blobs)
{
$CopyFileName = $Blob.Name
Write-Host "[Copying]: " $CopyFileName
$BlobCopy = Start-CopyAzureStorageBlob -Context $SrcStgContext -SrcContainer $SrcStgContainer -SrcBlob $Blob.Name `
-DestContext $DestStgContext -DestContainer $DestStgContainer -DestBlob $Blob.Name
$BlobCopyArray += $BlobCopy
}
Write-Host " "
}
Else
{
#Copy a specified file:
Write-Host "[Copying]: " $CopySpecificFileName
$BlobSpecificFileName = Get-AzureStorageBlob -Context $SrcStgContext -Container $SrcStgContainer -Blob $CopySpecificFileName
$BlobCopySpecificFile = Start-CopyAzureStorageBlob -Context $SrcStgContext -SrcContainer $SrcStgContainer -SrcBlob $BlobSpecificFileName.Name `
-DestContext $DestStgContext -DestContainer $DestStgContainer -DestBlob $BlobSpecificFileName.Name
Write-Host " "
}

#Delay/Wait:
Write-Host "[Waiting]:" $WaitBeforeCheckingCopyStatus "secs before checking copy status..."
Start-Sleep -s $WaitBeforeCheckingCopyStatus
Write-Host " "

#Check Copy Status:
If([string]::IsNullOrEmpty($CopySpecificFileName))
{
#Check Copy Status for "Copy all container contents":
#Re-run this block of code if copying files of larger size and need updated copy info
foreach ($BlobCopy in $BlobCopyArray)
{
Write-Host "[Copy Status]:"
$CopyState = $BlobCopy | Get-AzureStorageBlobCopyState

$MessageFileName = $CopyState.Source.AbsolutePath -replace "%20", " "
$MessageFileName = split-path $MessageFileName -leaf
$MessageFileName = "File Name: " + $MessageFileName
Write-Host $MessageFileName

$MessageStatus = "Copy Status: " + $CopyState.Status
If ($CopyState.Status -eq "Success")
{
Write-Host $MessageStatus -ForegroundColor Green
}
Else
{
Write-Host $MessageStatus -ForegroundColor Red
}
$MessagePercent = "Copy Percent: " + "{0:N2}%" -f (($CopyState.BytesCopied/$CopyState.TotalBytes)*100)
Write-Host $MessagePercent

$MessageBytes = "Copy Bytes: " + $CopyState.BytesCopied + "/" + $CopyState.TotalBytes + " copied"
Write-Host $MessageBytes

$MessageCompleteTime = "Completed Time: " + $CopyState.CompletionTime
Write-Host $MessageCompleteTime
Write-Host " "
}
}
Else
{
#Check Copy Status for a single file copy:
Write-Host "[Copy Status]:"
$CopyStateSpecificFileCopy = $CopySpecificFileCopy | Get-AzureStorageBlobCopyState
$MessageFileNameSpecificFileCopy = $CopyStateSpecificFileCopy.Source.AbsolutePath -replace "%20", " "
$MessageFileNameSpecificFileCopy = Split-Path $CopyStateSpecificFileCopyFileName -Leaf
$MessageSpecificFileCopy = $CopyStateSpecificFileCopyFileName + " " + $CopyStateSpecificFileCopy.Status + " {0:N2}%" -f (($CopyStateSpecificFileCopy.BytesCopied/$CopyStateSpecificFileCopy.TotalBytes)*100)
$MessageFileNameSpecificFileCopy = "File Name: " + $MessageFileNameSpecificFileCopy
Write-Host $MessageFileNameSpecificFileCopy
$MessageStatusSpecificFileCopy = "Copy Status: " + $CopyStateSpecificFileCopy.Status
If ($CopyStateSpecificFileCopy.Status -eq "Success")
{
Write-Host $MessageStatusSpecificFileCopy -ForegroundColor Green
}
Else
{
Write-Host $MessageStatusSpecificFileCopy -ForegroundColor Red
}
$MessagePercentSpecificFileCopy = "{0:N2}%" -f (($CopyStateSpecificFileCopy.BytesCopied/$CopyStateSpecificFileCopy.TotalBytes)*100)
$MessagePercentSpecificFileCopy = "Copy Percent: " + $MessagePercentSpecificFileCopy
Write-Host $MessagePercentSpecificFileCopy

$MessageBytesSpecificFileCopy = "Copy Bytes: " + $CopyStateSpecificFileCopy.BytesCopied + "/" + $CopyStateSpecificFileCopy.TotalBytes + " copied"
Write-Host $MessageBytesSpecificFileCopy

$MessageCompleteTime = "Completed Time: " + $CopyStateSpecificFileCopy.CompletionTime
Write-Host $MessageCompleteTime
}


Windows Powershell ISE output: