Posted on February 3, 2016 · Posted in Powershell

Copying Large Files Using BITS and PowerShell

As a rule, in local (and global) networks files are transferred between the systems using SMB, FTP or HTTP protocols. The problem of all these protocols is some troubles with resuming the download of the large files, which can become even worse if the channel is slow or unstable. Moreover, when copying files using these protocols the whole bandwidth between a server and a recipient is used, which may negatively affect the network performance and the work of other apps. (It is not always possible to configure QoS policies as necessary.) In this article, we’ll consider how to use BITS protocol and Powershell to copy large files if the channel is slow or unstable.

BITS Protocol

BITS (Background Intelligent Transfer service) is a Windows service used to transfer files between the systems. Windows Update (including WSUS) and SCCM distribution points transfer files to the target computers using this protocol.

Using BITS protocol, you can transfer files between computers (either download or upload files).

The Advantages of Using BITS Protocol:

  • BITS is the intelligent protocol able to control the used bandwidth not to affect the work of other network apps. BITS can use only the free band and dynamically change the data rate during the transfer (if other applications increase the network use)
  • A BITS task will be automatically resumed in case of disruptions or computer restarts
  • A file can be downloaded in the background, unnoticed by a user
  • The recipient side and the server side do not require a deployed IIS server

Thus, BITS is a preferable protocol to transfer large files in slow networks.

Note. Robocopy.exe utility allows to resume file copying if the connection has been broken.

OS and Powershell Version Requirements

BITS protocol appeared in Windows XP, in which bitsadmin.exe utility could be used to manage BITS tasks. The utility is still supported, but is deprecated. To manage BITS jobs, it is preferable to use special Powershell cmdlets.

To work under this scenario, we need Windows Vista or Windows Server 2008 or higher and Powershell 2.0 or higher.

Tip. It is possible to use Windows Server 2003 as well. In this case you will have to install KB 923845 update and PowerShell 2.0

BITS support is required on the side of both client and server.

How to Download a File Using BITS Protocol using Powershell

Suppose that we have to download a file stored in HTTP on the IIS server ( It is supposed that anonymous access to the server is possible. (Later we’ll consider access with authentication).

First of all, import BITS module in your Powershell session:

Import-Module BitsTransfer

After the module is imported, the list of all available commands can be displayed as follows:

get-command *-BITS*

BitsTransfer PowerShell module

As we can see, only 8 cmdlets are available.

Synchronous BITS File Transfer

To download a file using BITS protocol, use the following command:

Start-BitsTransfer –source -destination c:\temp
Start-BitsTransfer source

The message “This is a file transfer that uses the Background Intelligent Transfer service (BITS)” means that the specified file is being downloaded using BITS.

In this case the cmdlet has started the download in a synchronous mode. The download is similar to a common process of file copying, with a progress bar displayed on the screen showing the download status. If a computer is restarted, the download won’t be resumed.

Asynchronous BITS File Transfer

BITS download can be started in the asynchronous mode as well. To do it, add –asynchronous parameter to the command shown above. In this mode, if something happens (server or client restart, connection disruption, etc.), the task will automatically resume and the download will be continue.

Start-BitsTransfer -source -destination c:\temp -asynchronous

Asynchronous BITS File Transfer

Important. By default, Start-BitsTransfer runs with Foreground priority (the highest possible one). It is supposed that the download started in this mode will compete with other processes for the channel bandwidth. To avoid it, you have to explicitly set any other priority as an argument of the command, e. g., -Priority low

Start-BitsTransfer -source -destination c:\temp -asynchronous -Priority low

In this case, the file transfer process is not displayed on the screen. The task status can be obtained using Get-BitsTransfer cmdlet:

Get-BitsTransfer | fl

Get-BitsTransfer status

The command returns the transfer status (in this case the transfer is over: Transferred), the info about the number of bytes transferred, the time the file has been created and the time the task is completed.

You can see the status of all BITS tasks in tableform:

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

When using the asynchronous transfer mode, a temporary file with TMP extension is created (by default, it is hidden in Windows Explorer). To convert it into the source file, run the command Complete-BitsTransfer:

Get-BitsTransfer | Complete-BitsTransfer


After that, the BITS download task is considered to be completed and is removed from the list of jobs.

If the server, where the file is stored, requires user authentication, the following command will allow to show a window to enter user data and access the resource:

Start-BitsTransfer -source -destination c:\temp -asynchronous -Priority low -Authentication NTLM -Credential Get-Credential

BITS transfer with NTLM Auth

To make it easier to track the results of a BITS task, you can use a simple script, which allows to track the task progress and displays the download percentage on the screen. After the download is over, the script converts the file into the source format:

Import-Module BitsTransfer
$bitsjob = Start-BitsTransfer -Source -Destination c:\temp -Asynchronous
while( ($bitsjob.JobState.ToString() -eq 'Transferring') -or ($bitsjob.JobState.ToString() -eq 'Connecting') )
Write-host $bitsjob.JobState.ToString()
$Proc = ($bitsjob.BytesTransferred / $bitsjob.BytesTotal) * 100
Write-Host $Proc “%”
Sleep 3
Complete-BitsTransfer -BitsJob $bitsjob

How to Copy the Directory Contents Using BITS

As we already told, BITS doesn’t require a Web-server, and it means that we can copy files directly from other Windows computers or shared folders:

Start-BitsTransfer -Source \\lon-rep01\os\RHEL4.8-x86_64-AS-DVD.iso -Destination c:\temp -Asynchronous

BitsTransfer cannot recursively copy files and folders from a certain directory or files used by other programs. To copy all files and subdirectories from the specified shared folder, use this script:

Import-Module BitsTransfer
$folders = Get-ChildItem -Name -Path $source -Directory -Recurse
$bitsjob = Start-BitsTransfer -Source $Source\*.* -Destination $Destination -asynchronous -Priority low
while( ($bitsjob.JobState.ToString() -eq 'Transferring') -or ($bitsjob.JobState.ToString() -eq 'Connecting') )
Sleep 4
Complete-BitsTransfer -BitsJob $bitsjob
foreach ($i in $folders)
$exists = Test-Path $Destination\$i
if ($exists -eq $false) {New-Item $Destination\$i -ItemType Directory}
$bitsjob = Start-BitsTransfer -Source $Source\$i\*.* -Destination $Destination\$i -asynchronous -Priority low
while( ($bitsjob.JobState.ToString() -eq 'Transferring') -or ($bitsjob.JobState.ToString() -eq 'Connecting') )
Sleep 4
Complete-BitsTransfer -BitsJob $bitsjob

recursively download folder using bits and powershellThus, using BITS features is a great alternative to the common file copying using SMB protocol. BITS file transfer task is performed despite of connection disruptions or computer restarts, and doesn’t much occupy the bandwidth without interfering with other apps. BITS will be the best solution to transfer ISO files and copying virtual machine files.

Related Articles