How do I check and Update a web.config file (XML)

I am working on a script to check for a particular node in a web.config file for the SharePoint Team.
The idea is to check if the node exist. If so, check to see if the request limits are set to “maxAllowedContentLength”,”83886080″
If so, all is well. If not set “maxAllowedContentLength”,”83886080″.
If the node does not exist, add it.
I am also logging my results and traping any errors. You may want to add or delete directories in the $xdir array. The -recurse function is an all or nothing sort of thing. Excluding directories is not supported. Hopefully in the next release!

BTW: if you copy this, you will need to remove the back ticks (`) from the begining of lines 73-79. I had to add them so WordPress would show the (Greater than, Less than) properly.

###### Start Posh Script ########

function write-log([string]$info){
if($loginitialized -eq $false){
#$FileHeader > $logfile
$script:loginitialized = $True
$info >> $logfile
#---------Logfile Info----------#
$script:UseInfo = $($(get-date -format MM/dd/yyyy-HH:mm:ss) + '`t' + $env:username + '`t')

Trap [Exception] {
write-log $('$UseInfo`t$_. - Line:(' + $($_.InvocationInfo.ScriptLineNUmber)+':'+$($_.InvocationInfo.OffsetInLine)+ ') ' + $($_.InvocationInfo.Line))

$xdir = @('_app_bin','_vti_pvt','App_Browsers','App_GlobalResources','aspnet_client','bin','wpcatalog','wpresources')
$LogPath = Test-Path 'E:\LogFiles\ps\UpdateWebConfig' -pathType container
If ($LogPath) {
$script:logfile = 'E:\LogFiles\ps\UpdateWebConfig\WebConfig Update - $(get-date -format MMddyy-HHmmss).log'
$script:loginitialized = $false
} Else { New-Item 'E:\LogFiles\ps\UpdateWebConfig' -type directory
$script:logfile = 'E:\LogFiles\ps\UpdateWebConfig\WebConfig Update - $(get-date -format MMddyy-HHmmss).log'
$script:loginitialized = $false
$d = Get-Date -f MMddyy-HHmmss
Write-log '***Application Information***'
Write-log 'Filename: UpdateWebConfig.ps1'
Write-Log 'Created by: $env:username'
Write-Log 'Last Modified: $d'
Write-Log '***Application Information***'

$ErrorActionPreference = 'SilentlyContinue'
$rl = '83886080'
#$wc = Get-ChildItem -Recurse C:\Scripts\xml -include *.config
$wc = Get-ChildItem -Recurse E:\inetpub\wwwroot\wss\VirtualDirectories -include web.config |
where {$xdir -notcontains (Split-Path $_.DirectoryName -Leaf -EA SilentlyContinue)}

$XML = New-Object xml

foreach ($item in $wc){
$wtc = gc $item | Select-String 'requestLimits' -quiet
If ($wtc) {
$wcToChange = $XML.configuration.'system.webServer'.security.requestFiltering.requestLimits.GetAttribute('maxAllowedContentLength')
If ($wcToChange -eq $rl) {
Write-Host '$item is OK' -ForegroundColor Green
write-log '$item is OK'
Else {
Write-Host '$item is NOT OK maxAllowedContentLength = $wcToChange' -ForegroundColor Red
write-log '$item is NOT OK maxAllowedContentLength = $wcToChange'
write-log 'Backup File: `t$Item.bak-$d'
$wtc = $XML.configuration.'system.webServer'.security.requestFiltering.requestLimits.GetAttribute('maxAllowedContentLength')
write-log '$item is NOW OK maxAllowedContentLength = $rl'
write-log }
} Else {
Write-Host '$item is NOT OK' -ForegroundColor Red
Write-Host 'Need to Add RequestFiltering' -ForegroundColor Red
write-log 'Need to Add RequestFiltering to web.config file'
write-log 'Backup File: `t$Item.bak-$d'
# new system.webServer node and child nodes
[Xml]$sweb = @'
`<requestLimits maxAllowedContentLength='83886080'/>

# import and set the new system.webServer node
$newNode = $XML.ImportNode($sweb.'system.webServer', $true)
# append new system.webServer node
# check (this displays the results on the screen)
write-log $item
write-log `"requestLimits maxAllowedContentLength='83886080'"
write-log 'added to web.config file'

############# End POSH Script ###############

Powershell, Sans, Excel and XML

Here is a function that uses the San Surfer command line tool to pull the World Wide Name and World Wide Port Names from a QLogic HBA. I needed a lot of help with this one, and I got it.
It uses PSExec to run SCLI.EXE on the remote server.
Function SanCLI($strComputer) {
If (Test-Path "\\$strComputer\C$\Program Files\SANsurferCLI\scli.exe") {
$rRow = $row
$psinfoOutput = c:\psTools\psexec.exe \\$strComputer -w "C:\Program Files\QLogic Corporation\SANsurferCLI" "C:\Program Files\QLogic Corporation\SANsurferCLI\scli.exe" -I ALL -X #$xml = [xml]($psinfoOutput | where{$_})
$a = $xml.QLogic.HBA[0].GeneralInfo
$b = $xml.QLogic.HBA[1].GeneralInfo
$ws1.Cells.Item($rRow,17) = $a.Model
$ws1.Cells.Item($rRow,18) = $a.WWNN
$ws1.Cells.Item($rRow,19) = $a.WWPN
$ws1.Cells.Item($rRow,20) = $a.DriverVersion
$ws1.Cells.Item($rRow,21) = $a.BIOSVersion
$ws1.Cells.Item($rRow,22) = $a.FirmwareVersion
$ws1.Cells.Item($rRow,17) = $b.Model
$ws1.Cells.Item($rRow,18) = $b.WWNN
$ws1.Cells.Item($rRow,19) = $b.WWPN
$ws1.Cells.Item($rRow,20) = $b.DriverVersion
$ws1.Cells.Item($rRow,21) = $b.BIOSVersion
$ws1.Cells.Item($rRow,22) = $b.FirmwareVersion
Else {
Copy-Item D:\QLogic\scli*.exe -destination \\$strComputer\C$\Temp
c:\psTools\psexec.exe \\$strComputer -w "C:\Temp" "C:\Temp\"
$row = $rRow

But, you say you don’t have QLogic HBA’s. How can I get this information?
You can use the utility from Microsoft called FCInfo.exe. (Fiber Channel Information, clever yes?)
It is available at this location:
Since fcinfo isn’t officially supported in Windows 2008 you can download the tools for Windows 2008 from the vendor HBA website.
For Windows collection the command “scli” (Qlogic) or “hbacmd” (Emulex) is comparable to fcinfo.
Here is a function I wrote using FCInfo and psexec to poll a number of machines:
Function FCInfo ($strComputer) {
$xRow = $rRow
$PSpath = C:\PSTools
If (Test-Path "C:\PSTools\fcinfo.exe") {
$wwn = C:\PSToolspsexec.exe \\$strComputer $PSPath fcinfo.exe /details

$adapter = $wwn | Select-String -pattern "Adapter:" -allmatches -simplematch
$ws.Cells.Item($rRow,16) = $adapter[0]
$ws.Cells.Item($rRow,16) = $adapter[1]
$rRow = $rRow - 1
$node_wwn = $wwn | Select-String -pattern "node_wwn:" -allmatches -simplematch
$ws.Cells.Item($rRow,17) = $node_wwn[0]
$ws.Cells.Item($rRow,17) = $node_wwn[1]
$rRow = $rRow - 1
$port_wwn = $wwn | Select-String -pattern "port_wwn:" -allmatches -simplematch
$ws.Cells.Item($rRow,18) = $port_wwn[0]
$ws.Cells.Item($rRow,18) = $port_wwn[1]
$rRow = $xRow

Here is some info from Wikipedia on HBA’s and World Wide Names:
Today, the term host bus adapter (HBA) is most often used to refer to a Fibre Channel interface card.
There are two types of WWNs on a HBA; a node WWN (WWNN), which is shared by all ports on a host bus adapter, and a port WWN (WWPN), which is unique to each port.