The script allows to apply web.config modifications using an annotated input file containing deltas that need to be imported. This lets you run the script once and have the changes/deltas be applied to all web configs for the web app affected across the farm, as well as ensures that any new servers added later will get the same chages automatically.

As an example:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<configuration xmlns:wcm="urn:sharepointutil:webconfigmod">

<SharePoint>
<BlobCache location="d:\blobcache" wcm:type="EnsureAttribute" wcm:id="location,max-age,enabled" enabled="true" max-age="3600" />
</SharePoint>
<connectionStrings wcm:type="EnsureSection">
<add wcm:id="name" name="default" connectionString="Data Source=sql001;Initial Catalog=Data;Integrated Security=True" providerName="System.Data.SqlClient" />
</connectionStrings>
</configuration>

The above is going to enable blob cache, and add a connection string while ensuring that the <connectionStrings> section is there (which it is not by default).

The deltas are annotated with the "wcm:id" attribute which serves a dual purpose - 1) markign the delta within the file, and specifying an attribute that can be used to identify the node uniquely. The "wcm:type" attribute specifies the kind of opperation being performed as per (link). The default value for the wcm:type is EnsureChildNode

param([string]$op = 'apply', [string]$literalPath, [string]$webApplicationUrl, [string]$modOwner)

Add-PSSnapIn Microsoft.SharePoint.Powershell -ea SilentlyContinue

$nswcm = "urn:sharepointutil:webconfigmod";

function Apply-SPWebConfigModifications([string]$literalPath, [string]$webApplicationUrl, [string]$modOwner = $nswcm){

    $wa = Get-SPWebApplication $webApplicationUrl

    $xml = [xml](gc -literalpath $literalpath)
    $xns = new-object System.Xml.XmlNamespaceManager $xml.NameTable
    $xns.AddNamespace("wcm", $nswcm)
    $xml.SelectNodes("//*[@wcm:id or @wcm:type]", $xns) | %{
        $node = $_
        $ids= $_.GetAttribute("id", $nswcm);
        $type= $_.GetAttribute("type", $nswcm);
        if ([string]::isnullorempty($type)){
            $type = "EnsureChildNode"
        }
        $sType = [enum]::Parse([Microsoft.SharePoint.Administration.SPWebConfigModification+SPWebConfigModificationType], $type, $true)
        
        if ($type -ieq 'EnsureAttribute'){
            if ([string]::isnullorempty($ids)){
                write-host "id attribute must be specified for the EnsureAttribute mode"
                continue
            }
            $arid = $ids.Split(',') #multiple attributes per node might be assigned
        } else {
            $arid = $ids
        }
        
        $arid | %{
        
            $id = $_.Trim()

            $path = [string]::Join("/", ($node.SelectNodes("ancestor::*") | %{ $_.LocalName} ) )
            if ($type -ieq 'EnsureChildNode'){
                $name = '{0}[@{1}=''{2}'']' -f $node.LocalName, $id, $node.GetAttribute($id)                
                $clone = $node.Clone();
                $clone.RemoveAttribute("id", $nswcm)
                $clone.RemoveAttribute("type", $nswcm)
                $value = $clone.OuterXml
            } elseif ($type -ieq 'EnsureSection'){
                $name = $node.LocalName
                $value = '<{0}> </{0}>' -f $name
            } elseif ($type -ieq 'EnsureAttribute') {
                $path = [string]::Join("/", ($node.SelectNodes("ancestor-or-self::*") | %{ $_.LocalName} ) )
                $name = $id
                $value = $node.GetAttribute($id)
            }
            
            $mod = new-object Microsoft.SharePoint.Administration.SPWebConfigModification
            $mod.Name = $name
            $mod.Path = $path
            $mod.Owner = $modOwner
            $mod.Type = $sType
            $mod.Value = $value
            write-host "$sType under $path, xml: $value"
            $wa.WebConfigModifications.Add($mod)        
        }
    }

    $wa.Update();
    $wa.Parent.ApplyWebConfigModifications() 
}

function Clear-SPWebConfigModifications([string]$webApplicationUrl, [string]$modOwner = $nswcm){

    $wa = Get-SPWebApplication $webApplicationUrl
        if ($wa.WebConfigModifications -ne $null){
        ($wa.WebConfigModifications | ?{ $_.Owner -ieq $modOwner}).Clone() | %{ 
            $wa.WebConfigModifications.Remove($_) | out-null
            write-host $_.Type $_.Value
        }
        $wa.Update();
        $wa.Parent.ApplyWebConfigModifications() 
    }
}

#main
if ([string]::isnullorempty($modOwner)){
    $modOwner = $nswcm
}

if ([string]::isnullorempty($webApplicationUrl)){
    write-host -ForegroundColor red "-webApplicationUrl argument is required"
    exit 1
}

if ($op -ieq 'apply'){
    Apply-SPWebConfigModifications -literalPath $literalPath -webApplicationUrl $webApplicationUrl -modOwner $modOwner
} elseif ($op -ieq 'clear'){
    Clear-SPWebConfigModifications -webApplicationUrl $webApplicationUrl -modOwner $modOwner
} else
{
    write-host -ForegroundColor red "unrecognized parameter -op:  " + $op
    exit 1
}

Last edited Feb 16, 2012 at 5:11 AM by epranav, version 2

Comments

No comments yet.