One of the things we learn early in our SharePoint careers was not to manually edit the web.config files of a web application. SharePoint involves multiple servers and has its own mechanisms for managing web.config updates.
Previously, I’ve created xml files with web.config modifications and copied those to each WFE. Those changes are merged into the initial web.config by SharePoint.
I’ve always been vaguely aware of there being a better way, but never needed to track it down from an IT point of view. Last week, however we wanted to change a setting to enable blobcache on the servers hosting a particular web application so decided to use the opportunity to figure out a ‘best way’ to do this.
Enter, stage left, the SPWebConfigModification class (note, that link is to SharePoint 2010, but SP2013 works the same way).
We can create a collection of configuration changes that get applied by SharePoint via a timer job. That collection is generated through code and is persistent – we can add and remove changes over time, but they are stored in the farm config and will get applied each time we add a new server or update the web application IIS files.
A search of the web turned up an article by Ingo Karstein that had the right approach but brute forced everything by referencing SharePoint DLLs directly. A bit of experimentation showed that we didn’t need to do this – SharePoint PowerShell has everything we need.
Sample code is below. The code will first enumerate the collection of SPWebConfigurationModifications for our web application and remove any that have the same owner value as our script uses. It then adds a new modification to set the value of an attribute (the blobcache ‘enabled’ setting) to true. More modifications can be added into the script and these will be added to the collection. The mods are applied by SharePoint in sequence.
It needs some tidying but it works well. Read the documentation on how the modifications work carefully – it’s possible to work with an element or an attribute and you can add and remove stuff. Remember that other solutions may be adding modifications as well – make sure you don’t remove those.
As always, this stuff is provided ‘as is’ and I am not responsible for the damage you can wreak on your SharePoint farm. Test first and make sure you understand what this code does before using on production.
# Load SharePoint PowerShell PSSnapIn and the main SharePoint .net library
Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue
#set a few variables for the script
$owner = "NimbusPublishingModifications" $webappurl = "https://share2013.proj.local/"
#Get the web application we want to work with
$webapp = get-spwebapplication $webappurl
#get the Foundation Web Application Service (the one that puts the content web apps on servers)
$farmservices = $webapp.Farm.Services | where { $_.TypeName -eq "Microsoft SharePoint Foundation Web Application" }
#get the list of existing web config modifications for our web app
$existingModifications = @(); $webapp.WebConfigModifications | where-object { $_.Owner -eq $owner } | foreach-object { $existingModifications = $existingModifications + $\_}
#remove any modofications that match our owner value (i.e. strip out our old mods before we re-add them)
$existingModifications | foreach-object{ $webapp.WebConfigModifications.Remove($\_) }
#create a new web config modification
$newModification = new-object "Microsoft.SharePoint.Administration.SPWebConfigModification"
$newModification.Path = "configuration/SharePoint/BlobCache"
$newModification.Name = "enabled"
$newModification.Sequence = 0
$newModification.Owner = $owner
$newModification.Type = 1
#for the enum value "SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode"
$newModification.Value = "true"
#add our web config modification to the stack of mods that are applied
$webapp.WebConfigModifications.Add($newModification)
$webapp.Update()
#trigger the process of rebuildig the web config files on content web applications
$farmServices.ApplyWebConfigModifications()