function Get-AppSettingPrivateXml { <# .SYNOPSIS Returns an appSetting value from the specified file content .DESCRIPTION Returns an appSetting value from the specified file content .PARAMETER Key [string] The name of the key to get the value from, if it exists. .PARAMETER FileContent [xml] The file content to parse .PARAMETER SuppressWarnings [switch] Suppress warnings about keys not found .OUTPUTS Can return $null if key not found #> [CmdletBinding()] param ( [string]$Key, [xml]$FileContent, [switch]$SuppressWarnings ) $logLead = (Get-LogLeadName) ## Beware of the case of more than one appSettings element in case we run into issues, le sigh ## Let's go ahead and let the person reading the logs know that there were more than one section $appSettingsCollection = @($FileContent.SelectNodes('//appSettings')) if ($appSettingsCollection.Count -gt 1) { Write-Warning "$logLead : More than one appSettings section found to manipulate in [$FilePath]" foreach($appSettingElement in $appSettingsCollection) { $fullPath = $appSettingElement.Name $parentElement = $appSettingElement.ParentNode while ($null -ne $parentElement) { if($parentElement.Path) { $fullPath = $parentElement.Name + '[path=' + $parentElement.Path + ']/' + $fullPath } else { $fullPath = $parentElement.Name + '/' + $fullPath } $parentElement = $parentElement.ParentNode } Write-Host "Too many appSettings: $fullPath" } } if ($appSettingsCollection.Count -eq 0) { ## We don't have an appSettings element to work with ## Announce that, then return $null Write-Warning "$logLead : Could not find an appSettings element at all in [$FilePath]. Returning `$null" return $null } ## Now that we have at least one location for settings, let's go see if we have an existing value $existingSettingValuesByKey = @($FileContent.configuration.SelectNodes("//appSettings/add[@key='$Key']")) ## Crap, we found more than one element with the same key. ## We can't resolve this, but honestly the system can't work with it this way either ## Something will absolutely break, make sure that's logged ## At the very least, let's give something for the app to work with, I guess if ($existingSettingValuesByKey.length -gt 1) { Write-Error "Found too many nodes with the same Key value in [$FilePath]!!" foreach($appSettingElement in $existingSettingValuesByKey) { $fullPath = $appSettingElement.Name $parentElement = $appSettingElement.ParentNode while ($null -ne $parentElement) { if($parentElement.Path) { $fullPath = $parentElement.Name + '[path=' + $parentElement.Path + ']/' + $fullPath } else { $fullPath = $parentElement.Name + '/' + $fullPath } $parentElement = $parentElement.ParentNode } Write-Host "Too many nodes: $fullPath" } ## Return the last value found as it is the most general setting. ## Honestly we should have a hard-break here because this should be resolved Write-Warning "$logLead : Returning the last found value. Fingers crossed." return $existingSettingValuesByKey[-1].Value } ## Now we either have a value in $existingSettingValuesByKey or we don't ## If we have one, we return that value, else return $null if ($existingSettingValuesByKey.length -eq 0) { ## We don't have a value if ($SuppressWarnings) { Write-Verbose "$logLead : Could not find appSetting key '$Key'." } else { Write-Warning "$logLead : Could not find appSetting key '$Key'." } return $null } else { ## We have the key and there's only one in the collection! return @($existingSettingValuesByKey)[0].Value } }