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.
This is because you do not download separate Updates for Office - you download the complete setup files for Office.
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:
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
The gif above shows how BranchCache LocalCache works. For better understanding, I moved the DataCache to the 😧 Drive.
What can you see?
Once the download completes, you can see that we saved 57 MB just by using BranchCache LocalCache - fantastic!
Basic Implementation
Implementation in SCCM is very simple. You just need to enable BranchCache on your source DP and on your PullDP:
Distmgr will enable BranchCache on the DP
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:
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:
They have a total size of ~15GB and savings should be around 45%:
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
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.