I had need to pull down a very large file (127 GB) from Windows Azure. In order to do so, I needed to be able to pause/resume as I moved my work laptop between locations (and internet connections).
To accomplish this, I used BitsTransfer PowerShell functionality.
(Note: Under the azure management console, I made sure the file was public, and grabbed the url to use as the source)
First step is to load the module:
Import-Module BitsTransfer
Next, I declare a few variables:
$source = "http://my.url"
$destination = "C:\localFolder\newFile.name"
$transferName = "MyTransfer"
I need the credentials for logging into Azure to pull the file.
$cred = Get-Credential
Being the asynchronous download:
Start-BitsTransfer -Source $source -Destination $destination -DisplayName $transferName -Asynchronous
The command prompt returns. I can close the PowerShell console window at this point. (If I do, I have to remember the Import-Module command when re-opening in the future). If I want to take some actions on the job, I will want to capture it in an object variable.
$myJob = Get-BitsTransfer $transferName
I can pause the transfer process with a simple command:
Suspend-BitsTransfer $job
I can resume it just as easily:
Resume-BitsTranfer -BitsJob $job -Asynchronous
For me, the biggest thing was to have my own status reporting. I wanted a simple, and clean message to let me know how much data has been transferred. And let me know when the process stops.
I start with a helper function. The BitsJob is going to report in number of bytes, and that means BIG numbers. So my function converts bytes into a friendlier string.
function Convert-DataSize([long]$numOfBytes)
{
[int] $cnt = 0
[double] $dBytes = $numOfBytes
for($i = 0; $i -lt 5; $i++)
{
$cnt = $i
[double] $results = [double]($dBytes /1024)
if ($results -lt 1) { break; }
$dBytes = $results
}
switch($cnt)
{
1 { return $dBytes.ToString("0.00") + " KB" }
2 { return $dBytes.ToString("0.00") + " MB" }
3 { return $dBytes.ToString("0.00") + " GB" }
4 { return $dBytes.ToString("0.00") + " TB" }
}
return $numOfBytes.ToString() + " B"
}
With my helper function established, I create a loop to display my message:
do
{
cls
$percentComplete = "(" + ($job.BytesTransferred / $job.BytesTotal * 100).ToString("0.00%") + ") "
$bytesTrans = Convert-DataSize($job.BytesTransferred)
$bytesTotal = Convert-DataSize($job.BytesTotal)
Write-Host $percentComplete $bytesTrans " of " $bytesTotal
Start-Sleep -s 5
if ($job.JobState -ne "Transferring") { break; }
}
while ($job.BytesTransferred -lt $job.BytesTotal)
$job #Displaying promoted properties of the BitsJob object.
The last step I need to remember is to complete the transfer process:
Complete-BitsTransfer $job
Just imagine how all this PowerShell looks in a nice clean script file. Add a little code to check if the job already exists, and some better error handling, I can launch this thing easily with a double-click, and let it run until it completes. (My big job took almost 40 hours based on the variety of connections I ended up attached too).
Thursday, September 19, 2013
Subscribe to:
Posts (Atom)