If you use local (and global) networks, you might know that files between systems are transferring by using SMB, FTP or HTTP protocols. The problem with all of these protocols is difficulties with the large files downloading. Also, this sort of problem is a common issue due to slow or unstable connection. When you copy files through these protocols, usually it takes all available bandwidth between the server and users. It may cause a poor network or applications performance (sometimes we cannot set up the proper QoS policies).

In this article, we will show you an alternative way to copy the large files with the BITS protocol using PowerShell.

Using BITS

BITS or Background Intelligent Transfer Service is a Windows service for transferring files between the systems. With the BITS protocol, you can transfer files between computers (download and upload files).

Benefits of using BITS:

BITS is an intelligent protocol, which can regulate the bandwidth usage. BITS can dynamically change the data transferring speed

File transferring is running in the background, so it is invisible for user

BITS can resume file transferring automatically even after network interruptions

BITS does not require a full-scale IIS server on the client (or server) side

So, BITS is the best protocol for transferring large files over slow networks.

How to download the BITS protocol using PowerShell

Let’s suppose that we need to download the file, which is stored on the HTTP server (http://10.2.2.148/erd65_32.iso).

First, we have to add BITS module support to the PowerShell:

Import-Module BitsTransfer

After that, we can see the list of all available commands:

get-command *-BITS*

As we can see, there are eight scripts are available.

Synchronous data transfer through BITS

To download the file with the BITS protocol, use the command:

Start-BitsTransfer –source http://10.2.2.148/erd65_32.iso -destination c:temp

Message This is a file transfer that uses the Background Intelligent Transfer service (BITS) says that the file is downloading right now with BITS protocol.

In this case, the script is begun downloading in synchronous mode. You can see the progress bar, which will show you a transferring status.

Note. If you want to restart your computer, you have to know, that the downloading process will not be renewed.

Asynchronous data transfer through BITS

You can run the process in the asynchronous mode. To do this you need to add the –asynchronous parameter in the command below. In this mode, if something happens (reboot the server, the client) the downloading process will automatically continue afterwards.

Start-BitsTransfer -source http://10.2.2.148/erd65_32.iso -destination c:temp –asynchronous

But in this mode we cannot see the transferring status, so we should use the Get-BitsTransfer command to check the status.

Get-BitsTransfer | fl

Also, you can check status in a tabular form:

Get-BitsTransfer | select DisplayName, BytesTotal, BytesTransferred, JobState | Format-Table –AutoSize

When you are using the asynchronous mode, it creates a temporary file (.tmp). To convert this file to the original file, use the command:

Get-BitsTransfer | Complete-BitsTransfer

After that, the downloading process will be done, and you will see it in the list.

If the server requires user authentication, use the following command to open an authentication window:

Start-BitsTransfer -source http://10.2.2.148/erd65_32.iso -destination c:temp -asynchronous -Priority low -Authentication NTLM -Credential Get-Credential

To make the process of result tracking easier, you can use a simple script that monitors the status and displays the transferring percentage on the screen.

After transferring, the script will convert the file to its original format:

Import-Module BitsTransfer

$job = Start-BitsTransfer -Source http://10.2.2.148/erd65_32.iso -Destination c:temp -Asynchronous

while( ($job.JobState.ToString() -eq ‘Transferring’) -or ($job.JobState.ToString() -eq ‘Connecting’) )

{

Write-host $Job.JobState.ToString()

$Pro = ($job.BytesTransferred / $job.BytesTotal) * 100

Write-Host $Pro “%”

Sleep 3

}

Complete-BitsTransfer -BitsJob $job

Copying the contents of the directory through BITS

As we said earlier, the BITS protocol does not require a full-scale IIS server. That means, that we can copy files directly from others Windows machines or shared folders:

Start-BitsTransfer -Source msk-rep01osrhel-server-7.0-x86_64-dvd.iso -Destination c:temp –Asynchronous

BITS cannot recursively copy files and folders from a specific directory. To copy all files with subfolders from the specific network directory, you should use this script:

Import-Module BitsTransfer

$Source=”msk-rep01os”

$Destination=”c:tmp”

$folders = Get-ChildItem -Name -Path $source -Directory -Recurse

$job = Start-BitsTransfer -Source $Source*.* -Destination $Destination -asynchronous -Priority low

while( ($job.JobState.ToString() -eq ‘Transferring’) -or ($job.JobState.ToString() -eq ‘Connecting’) )

{

Sleep 3

}

Complete-BitsTransfer -BitsJob $job

foreach ($i in $folders)

{

$exists = Test-Path $Destination$i

if ($exists -eq $false) {New-Item $Destination$i -ItemType Directory}

$job = Start-BitsTransfer -Source $Source$i*.* -Destination $Destination$i -asynchronous -Priority low

while( ($job.JobState.ToString() -eq ‘Transferring’) -or ($job.JobState.ToString() -eq ‘Connecting’) )

{

Sleep 3

}

Complete-BitsTransfer -BitsJob $job

}

That is all, guys. BITS is an excellent alternative to traditional transferring through well-known protocols. BITS is the optimal solution for transferring the large files (like ISO files), so try it out.