Speed-up Content Distribution with PullDPs and BranchCache
Published May 31 2019 06:13 AM 8,077 Views
Microsoft

Hello Everyone! I´m Stefan Röll, Premier Field Engineer (PFE) at Microsoft Germany for System Center Configuration Manager. One of my customers was challenged with large content distributions and relative slow connections to some satellite locations .

 

 

TL;DR

Pull Distribution Points (Pull DPs) can save you a lot of Bandwidth when used together with BranchCache, especially for downloads like Office 365ProPlus Updates, Definitions for Defender and (Boot)Images.

At my customer, I can see about 30% savings compared to Standard DPs. Especially for slow connected Systems, this can be a huge benefit.

 

The Challenge

My customer is starting to deploy Office 365ProPlus Updates including multiple Languages using SCCM.

We have noticed that this will cause a huge amount of data that needs to be sent to all Distribution Points each month.

When you download a single O365 Update with multiple Languages, you quickly end up with 6-8GB of Data.

Picture1.png

 

This is because you do not download separate Updates for Office - you download the complete setup files for Office.

Picture2.png  

So how to get all that Data to the Distribution Points?

 

BranchCache LocalCache

BranchCache LocalCache is one of my favourite features of BranchCache, but unfortunately not well known.

No matter in which mode you are running BranchCache (Local, Distributed or Hosted), when downloading data BranchCache will always ask its LocalCache (aka DataCache) first, before asking peers in the Subnet (Distributed) or the HostedCache Server. In LocalCache mode it will not request data from other sources.

 

Proof of Concept

First, I wanted to find out if BranchCache LocalCache can help with Office Updates.

To do that I used ddpeval.exe and checked the data source of the package.

This will give you the Data Deduplication savings, which is what you can expect as download savings:

 

Picture3.png

 

As you can see, we can expect about 34% savings when using Data Deduplication in this example.

As BranchCache is based on the same technology, you can expect similar savings.

 

For testing, I used the following PS-Script to download two Office Language Files from a Distribution Point.

 

$Cred = Get-Credential

 

$Source1"http://" + "dp01.sccm.lab/sms_dp_smspkg$/15f39dd2-5662-49b2-a502-9367d5b6fd86/office/data/16.0.11629.20136/stream.x86.en-us.dat"

$Source2"http://" + "dp01.sccm.lab/sms_dp_smspkg$/15f39dd2-5662-49b2-a502-9367d5b6fd86/office/data/16.0.11629.20136/stream.x86.de-de.dat"

 

Start-BitsTransfer -Source $Source1 -Destination "C:\Temp\stream.x86.en-us.dat" -Priority Low -Authentication Ntlm -Credential $Cred

Start-BitsTransfer -Source $Source2 -Destination "C:\Temp\stream.x86.de-de.dat" -Priority Low -Authentication Ntlm -Credential $Cred

 

In addition, I used the following Script to monitor the download on the Client side:

 

do

{

    $FromServer = "\BranchCache\BITS: Bytes from server"

    $FromCache  = "\BranchCache\BITS: Bytes from cache"

    $Time = Get-Date -Format hh:mm:ss

 

    $TotalMegaBytesfromServer = [math]::round(((Get-Counter $FromServer).CounterSamples.CookedValue / 1024 / 1024),0)

    $TotalMegaBytesfromCache  = [math]::round(((Get-Counter $FromCache ).CounterSamples.CookedValue / 1024 / 1024),0)

 

    $Ratio = If($TotalMegaBytesfromServer -gt 0){[math]::round(($TotalMegaBytesfromCache*100/($TotalMegaBytesfromServer+$TotalMegaBytesfromCache)),2)}else{0}

 

    Write-Output "MByte from Server: $($TotalMegaBytesfromServer) - MByte from Cache: $($TotalMegaBytesfromCache) - CacheRatio: $Ratio - Time: $Time"

    Start-Sleep -Seconds 10

}

until ($false)

 

Demo Download

PoC_Download_new_2.0_final.gif

 

The gif above shows how BranchCache LocalCache works. For better understanding, I moved the DataCache to the 😧 Drive.

 

Picture4.png

 

What can you see?

  • The script and progress to download two Office language Files from a DP ( 1 )
  • The BranchCache download statistics ( 2 )
  • Although it downloads ( 4 ) to the C: drive, you can see that the 😧 drive has read/write access ( 3 )

 

Once the download completes, you can see that we saved 57 MB just by using BranchCache LocalCache - fantastic!

 

Picture5.png

Basic Implementation

Implementation in SCCM is very simple. You just need to enable BranchCache on your source DP and on your PullDP:

 Picture6.png

 

Distmgr will enable BranchCache on the DP

 Picture7.png

 

With Get-BCStatus you can check the BranchCache Configuration on the DPs.

  

Advanced Implementation

In the default configuration the DataCache for BranchCache is very small, and savings will be limited.

Therefore I´ve wrote a Baseline to tune the BranchCache settings. You still need to enable BC on your DPs as mentioned in the Basic Implementation above.

 

The Baseline checks and fixes the following things:

 

  • BranchCache Server Feature is installed
  • BranchCache Service is started and set to automatic startup
  • Configures BranchCache for LocalCache or DistributedCache
  • Moves the BranchChache Caches to the same drive as the ContentLib
    • My customer has a separate drive for the ContentLib
    • The drive has a lot of free space, so it´s ideal for BranchCache data
  • Configures BranchCache limit
    • DataCache 50% of the Drive
    • Ensures better download savings
    • HashCache 50% of the Drive
    • Helps if BranchCache enabled Clients are downloading from this DP
  • Configures a longer age time (70 days) for data in the cache
    • Ensures better download savings over time

 

You can use the Baseline as template for your environment but be sure to test it out before using it in production.

 

Discovery Script:

<#

# THIS SAMPLE CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,

# WHETHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED

# WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.

# IF THIS CODE AND INFORMATION IS MODIFIED, THE ENTIRE RISK OF USE OR RESULTS IN

# CONNECTION WITH THE USE OF THIS CODE AND INFORMATION REMAINS WITH THE USER.

#>

Import-Module BranchCache

$OK = $true

 

#Check if BranchCache Server Feature installed

$Feature = Get-WindowsFeature -Name BranchCache

if ($Feature.Installed -ne $true) {$OK = $false}

 

#Check BranchCache Service Status

$Service = Get-BCStatus

if ($Service.BranchCacheIsEnabled -ne "True") {$OK = $false}

if ($Service.ClientConfiguration.CurrentClientMode -ne "DistributedCache") {$OK = $false} #You need to decide if you want Distributed or local Cache

if ($Service.BranchCacheServiceStatus -ne "Running") {$OK = $false}

if ($Service.BranchCacheServiceStartType -ne "Automatic") {$OK = $false}

 

#Check BC location is same as SCCMContentLib

$HashCache = Get-BCHashCache -ErrorAction Stop

$DataCache = Get-BCDataCache -ErrorAction Stop

$ContentLibDrive = (Get-ItemProperty -Path "HKLM:\Software\Microsoft\SMS\DP" -Name ContentLibraryPath -ErrorAction SilentlyContinue).ContentLibraryPath

$ContentLibDrive = ($ContentLibDrive).SubString(0, 3)

$HashCacheDrive = ($HashCache.CacheFileDirectoryPath).SubString(0, 3)

$DataCacheDrive = ($DataCache.CacheFileDirectoryPath).SubString(0, 3)

if ($ContentLibDrive -ne $HashCacheDrive) {$OK = $false}

if ($ContentLibDrive -ne $DataCacheDrive) {$OK = $false}

 

#Check that Cache Sizes are correct

$HashCache = Get-ItemProperty -Path "HKLM:\Software\Microsoft\Windows NT\CurrentVersion\PeerDist\CacheMgr\Publication" -Name SizePercent -ErrorAction SilentlyContinue

if ($HashCache.SizePercent -ne 50) {$OK = $false}

$DataCache = Get-ItemProperty -Path "HKLM:\Software\Microsoft\Windows NT\CurrentVersion\PeerDist\CacheMgr\RePublication" -Name SizePercent -ErrorAction SilentlyContinue

if ($DataCache.SizePercent -ne 50) {$OK = $false}

 

#Check BranchCache MaxAge

$CacheAge = Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\PeerDist\Retrieval" -Name SegmentTTL -ErrorAction SilentlyContinue

if ($CacheAge.SegmentTTL -ne 70) {$OK = $false}

 

return $OK

 

Remediation Script:

<#

# THIS SAMPLE CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,

# WHETHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED

# WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.

# IF THIS CODE AND INFORMATION IS MODIFIED, THE ENTIRE RISK OF USE OR RESULTS IN

# CONNECTION WITH THE USE OF THIS CODE AND INFORMATION REMAINS WITH THE USER.

#>

Import-Module BranchCache

 

#Install BranchCache Server Feature if not installed

$Feature = Get-WindowsFeature -Name BranchCache

if ($Feature.Installed -ne $true) {Install-WindowsFeature -Name BranchCache}

 

#Fix BranchCache Service Status

$Service = Get-BCStatus

if ($Service.BranchCacheIsEnabled -ne "True") {Enable-BCDistributed -Force} #If you don�t want to enable Distributed Mode, use Enable-BCLocal

if ($Service.ClientConfiguration.CurrentClientMode -ne "DistributedCache") {Enable-BCDistributed -Force} #You need to decide if you want Distributed or local Cache

if ($Service.BranchCacheServiceStatus -ne "Running") {Start-Service PeerDistSvc}

if ($Service.BranchCacheServiceStartType -ne "Automatic") {Set-Service PeerDistSvc -StartupType Automatic}

 

#Fix BC location

$HashCache = Get-BCHashCache -ErrorAction Stop

$DataCache = Get-BCDataCache -ErrorAction Stop

$ContentLibDrive = (Get-ItemProperty -Path "HKLM:\Software\Microsoft\SMS\DP" -Name ContentLibraryPath -ErrorAction Stop).ContentLibraryPath

$ContentLibDrive = ($ContentLibDrive).SubString(0, 3)

$HashCacheDrive = ($HashCache.CacheFileDirectoryPath).SubString(0, 3)

$DataCacheDrive = ($DataCache.CacheFileDirectoryPath).SubString(0, 3)

$HashCacheDest = $ContentLibDrive + "BranchCache\Publication"

$DataCacheDest = $ContentLibDrive + "BranchCache\RePublication"

if ($ContentLibDrive -ne $HashCacheDrive) {

      New-Item -ItemType directory -Path $HashCacheDest -Force -ErrorAction Stop

       #Clear Cachce and restart service to ensure move works

      Clear-BCCache -Force -ErrorAction Stop

       Restart-Service PeerDistSvc -Force

       Get-BCHashCache | Set-BCCache -MoveTo $HashCacheDest -Force -ErrorAction Stop

}

if ($ContentLibDrive -ne $DataCacheDrive) {

       New-Item -ItemType directory -Path $DataCacheDest -Force -ErrorAction Stop

       #Clear Cachce and restart service to ensure move works

       Clear-BCCache -Force -ErrorAction Stop

       Restart-Service PeerDistSvc -Force

       Get-BCDataCache | Set-BCCache -MoveTo $DataCacheDest -Force -ErrorAction Stop

}

 

#FixCache Sizes

$HashCache = Get-ItemProperty -Path "HKLM:\Software\Microsoft\Windows NT\CurrentVersion\PeerDist\CacheMgr\Publication" -Name SizePercent -ErrorAction SilentlyContinue

if ($HashCache.SizePercent -ne 50) {Get-BCHashCache | Set-BCCache -Percentage 50 -Force}

$DataCache = Get-ItemProperty -Path "HKLM:\Software\Microsoft\Windows NT\CurrentVersion\PeerDist\CacheMgr\RePublication" -Name SizePercent -ErrorAction SilentlyContinue

if ($DataCache.SizePercent -ne 50) {Get-BCDataCache | Set-BCCache -Percentage 50 -Force}

 

#Fix BranchCache MaxAge

$CacheAge = Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\PeerDist\Retrieval" -Name SegmentTTL -ErrorAction SilentlyContinue

if ($CacheAge.SegmentTTL -ne 70) {Set-BCDataCacheEntryMaxAge -TimeDays 70 -Force}

 

Final Test

As a final test I have distributed four office updates with six different languages:

 Picture8.png

 

They have a total size of ~15GB and savings should be around 45%:

 Picture9.png

 

Picture10.png

 

Mission succeeded! We have saved ~45% of data just by enabling BranchCache 🙂

 

Happy BranchCaching!

 

Stefan Röll

Premier Field Engineer - Microsoft Germany

 

Changelog:

V1.0 - 05/31/2019 - initial release

V1.1 - 06/05/2019 - Fixed Bug in Discovery and Remediation Script

 

Disclaimer:
The sample scripts are not supported under any Microsoft standard support program or service. The sample scripts are provided AS IS without warranty of any kind. Microsoft further disclaims all implied warranties including, without limitation, any implied warranties of merchantability or of fitness for a particular purpose. The entire risk arising out of the use or performance of the sample scripts and documentation remains with you. In no event shall Microsoft, its authors, or anyone else involved in the creation, production, or delivery of the scripts be liable for any damages whatsoever (including, without limitation, damages for loss of business profits, business interruption, loss of business information, or other pecuniary loss) arising out of the use of or inability to use the sample scripts or documentation, even if Microsoft has been advised of the possibility of such damages.
 
3 Comments
Version history
Last update:
‎Jun 05 2019 04:43 AM
Updated by: