When using ConfigMgr in distributed environments, there are times when you want to limit how much bandwidth a client is using when downloading content. In all fairness, when having techniques like Peer Cache, and BranchCache at your disposal, you may get away by not limiting the bandwidth, but for most distributed environments you probably want to configure BITS to control how much bandwidth that is used over the WAN links. BITS is after all the component that is used for the actual downloads.
Note: When using BranchCache and LEDBAT for all of your CM traffic, you typically wonโt need to set a BITS limit, at least not for that traffic. BUT, you'll be surprised how many applications that are using BITS to download data from Internet, so chances are you might want to put some basic rules in place.
Creds: Some bits (I'm so funny), of this guide are totally stolen with pride from the Administrators Guide to BranchCache by the folks at 2Pint Software. They said it was ok as long as mentioned them and linked to the original guide, so there ๐ ). The remaining parts are from customer implementations and my own lab research.
The important BITS
First of all, and this is critical, please note that BITS have two "modes" it's job can run in: Background and Foreground.
Background jobs are designed to throttle, but Foreground jobs are designed NOT to throttle. Meaning you cannot throttle foreground BITS jobs via BITS Settings/Policies. The only way to throttle foreground BITS jobs is via the following methods:
- Use LEDBAT on the source (available in Windows Server 2016 or later)
- Use a third party kernel mode network filter driver (Available in the StifleR platform from 2Pint Software)
- Use traditional QoS on the network routers
So when are foreground jobs used you ask? Well, when you open Software Center and install either an application model application or a software update. Legacy packages still goes as background jobs even if started manually via Software Center, but application model applications or software updates does not. They need to be deployed as required in order for ConfigMgr to launch them as background jobs, and therefor being able to throttle them. Also note that task sequences that aren't configured for pre-caching the content will not use BITS at all.
Summary: Unless you really want to kill your WAN links, don't open Software Center on a remote client and install anything except legacy packages or task sequences configured for pre-caching.
Note: If you didn't read the above section carefully, read again.
Configuring BITS on the clients
BITS can be configured via both ConfigMgr client settings and group policy, but you have more granular options via group policy, and if you use the ConfigMgr Client Settings you basically kill BranchCache because of the missing "Ignore bandwidth limits if the source and the destination are on the same subnet " setting. So configuring BITS via group policy it is ๐
When configuring BITS via group policy there are two policies that you typically use. The work schedule and the maintenance schedule policies. The work schedule is where you do the main configuration, and the maintenance schedule can be used to override the work schedule if needed. In this guide, you simply just configure the work schedule.
To configure the work schedule policy, you create a new group policy object, and then you enable and configure the following policy:
Computer Configuration / Administrative Templates / Network / Background Intelligent Transfer Service / Setup a work schedule to limit the maximum network bandwidth used for BITS background transfers
As a good starting point, set the following values (adjust the bandwidth settings according to your WAN links):
- Select the Ignore bandwidth limits if the source and the destination are on the same subnet check box
- Work Days: Monday – Friday
- Daily Work Hours: 7am – 8 pm
- Bandwidth Limit During Work Hours: 4 Mbps for all priorities
- Bandwidth Limit During Non-Work Hours: 12 Mbps for all priorities

Verifying that BITS works
Verifying that the BITS works can be done by checking the event log on the client side. Windows 10 has detailed logging in the event viewer for its BITS transfers.
Here is a shiny script from Michael Niehaus (@mniehaus) that queries the event log on remote computers for BITS transfers.
$prefix = "MN-"
foreach ($i in 101..110)
{
$suffix = $i.ToString("000")
$vmName = "$prefix$suffix"
Get-WinEvent -ComputerName $vmName -FilterHashTable @{ LogName='*Bits*'; ID=4 } | % {
$_ | Add-Member -MemberType NoteProperty -Name jobTitle -Value $_.Properties[1].Value;
$_ | Add-Member -MemberType NoteProperty -Name bytesTransferred -Value $_.Properties[5].Value;
$_ | Add-Member -MemberType NoteProperty -Name bytesTransferredFromPeer -Value $_.Properties[6].Value -PassThru;
} | ? {$_.bytesTransferredFromPeer -gt 0} | Select MachineName, TimeCreated, jobTitle, bytesTransferred, bytesTransferredFromPeer | FT
}
In the preceding script you check for Event ID 4 which lists completed BITS jobs, and how much data that was copied from DPs vs Peers. Other events that can be interested are:
Event 3. BITS Job is created
Event 59. Your file gets added to the BITS job
Event 60. File is copied, and you can check to see if the peerProtocalFlags is set (it should be 1 if you are BranchCaching)
Here is another version of the script that I used in my lab. This loops through an OU in AD to find the machines instead of using a prefix/suffix type search:
# Loop through the Chicago OU in AD, and view BITS info
$Computers = Get-ADComputer -Filter * -Searchbase 'OU=Workstations Peer Cache Chicago,OU=ViaMonstra,DC=corp,DC=viamonstra,DC=com' | Select-Object -expand Name
foreach ($Computer in $Computers){
Get-WinEvent -ComputerName $Computer -FilterHashTable @{ LogName='*Bits*'; ID=4 } | % {
$_ | Add-Member -MemberType NoteProperty -Name jobTitle -Value $_.Properties[1].Value;
$_ | Add-Member -MemberType NoteProperty -Name bytesTransferred -Value $_.Properties[5].Value;
$_ | Add-Member -MemberType NoteProperty -Name bytesTransferredFromPeer -Value $_.Properties[6].Value -PassThru;
} | ? {$_.bytesTransferredFromPeer -gt 0} | Select MachineName, TimeCreated, jobTitle, bytesTransferred, bytesTransferredFromPeer | FT
}

You can also use PowerShell BITS commands or the legacy bitsadmin (to be removed) to check BITS status. Here is the output from running bitsadmin /monitor while download a file from ConfigMgr using BITS.

Troubleshooting BITS on the clients
In order to troubleshoot BITS, using the BITS PowerShell module is a really good start. Here is a post by PFE Kevin (Microsoft).
Troubleshooting BITS with PowerShell
http://blogs.technet.microsoft.com/cmpfekevin/2014/01/29/troubleshooting-bits-with-powershell
Another useful tip is resetting the BITS transfer queue. Here is a post by Nickolaj Andersen (@NickolajA).
Additional Resources
For dynamic control of the BITS bandwidth settings, you might want to check out the StifleR platform from 2Pint Software.
You also find related guides in this list:
- Setup Peer Caching in ConfigMgr Current Branch: https://deploymentresearch.com/600
- Setup BranchCache for ConfigMgr: https://deploymentresearch.com/608
- Setup Express Installation Files for ConfigMgr: http://www.windows-noob.com/forums/topic/15068-how-can-i-use-express-updates-when-patching-windows-10-with-quality-updates-in-system-center-configuration-manager-current-branch/
Is it possible to use BITS in WinPE? Sometimes we have to deploy Windows to an examination room of nearly 300 computers. It would be nice if we could use BITS before Windows is installed.
WinPE supports BITS natively, but you want to add BranchCache support which is not available by default. The OSD Toolkit solution from 2Pint Software will do that. There is a free version available for the community.
Thank you for your reply. Isn't BrancheCache a solution when you are dealing with a bad WAN-connection? We want to a solution to prevent the bandwidth of a network to be used entirely to download large files over a lot of computers. Like a Windows image. Do you have any experience with installing Windows in multicast with SCCM? Multicast in SCCM seems to be a vulnerable solution, but it is a great solution to prevent your network's bandwidth being used entirely to download a Windows image. At the moment we are using a different tool from SCCM to deploy Windows… Read more »
BranchCache is used for slow WAN links and/or mass deployments without multicast. I haven't touched multicast in many years, but its implementation in ConfigMgr is terrible and insecure since it still requires the use of a network access account. How large is your image?
Our image is between the 7 or 8 gbs.
That size image you can deploy within 2-3 hours to 300 computers using BranchCache (P2P). You might even be able to get away with it using the free community version of the OSD Toolkit that adds BranchCache to WinPE (the free version is a bit slower).
Does the free version also have BITS? Or is BITS only available on the paid version?
WinPE already has BITS, but the free version does include the BITS ACP for task sequences (either ConfigMgr or MDT extended with PSD).