如何在powershell中验证IIS web.config



不幸的是,在IIS中,如果在wwwroot\web.config和wwwroot\myapp\web.config中定义相同的设置,某些类型的设置将相互冲突,从而导致500.19错误。

例如允许使用的动词:

<security>
<requestFiltering>
<verbs allowUnlisted="false">
<add verb="HEAD" allowed="true" />
<add verb="POST" allowed="true" />
<add verb="GET" allowed="true" />
</verbs>
</requestFiltering>
</security>

同样不幸的是,PowerShell Set WebConfiguration在进行更改之前不会对此进行验证,并且一旦损坏,就无法删除错误的配置。

我需要一种在更改之前/之后验证配置的方法,这样我就可以回滚或采取行动。

我找到了这个解决方案:https://serverfault.com/questions/708079/is-there-a-cmd-tool-to-check-a-web-config-file-for-validity然而,它仅验证SYNTAX故障或仅验证非常重要的配置问题。

它不会检测到其他过滤器路径上的冲突:例如,无法添加类型为"add"且唯一密钥属性"verb"设置为"HEAD"的重复集合条目

我发现解决方案是创建一个在web.config中读取的函数,通过解析xml编译过滤器列表,然后为每个过滤器执行get-webconfiguration,过滤器要么返回一些东西,什么都不返回(如果没有要读取的设置(,要么返回一个异常(我们关心的是什么(

代码:

function Test-IISWebAppConfigIsValid
{
param (
[Parameter(Mandatory=$true,ValueFromPipeline=$true,ValueFromPipelineBYPropertyName=$true)]
[string]$AppName,
[string]$SiteName='Default Web Site'
)
process 
{
$Result = @{
IsValid=$false;
SiteName=$SiteName
AppName=$AppName
}
try
{
$result.Add("FileInfo",(Get-WebConfigFile -PSPath "IIS:Sites$SiteName$AppName"))
$Result.Add("FileExists",$result.FileInfo.Exists)
$result.Add("IsXML",$False)
#load the web.config
[xml]$ConfigXML =  $result.FileInfo | Get-Content
$result.IsXML = $true
#find all the elements in the config file
$Elements = $ConfigXML.SelectNodes("//node()[name() != 'add' and name() != 'remove' and name() != 'clear']") 

#extract the filters from the xpath by finding all the configured elements
$FilterList = @()
foreach ($el in $Elements)
{
$FilterStack = @()
$tempel = $el
while ($tempel.ParentNode -and $tempel -ne $ConfigXML.DocumentElement -and $tempel -ne $ConfigXML)
{
$name = $tempel.get_name()
if ($tempel.NodeType -eq 'Element')
{
$FilterSTack += $name
}
$tempel = $tempel.ParentNode
}
if ($FilterStack.Count -gt 0) {
[array]::Reverse($FilterStack)
$FilterList += "/"+[string]::Join("/",$FilterStack)
}
}
$Result.Add("FilterList", ($FilterList | Sort-Object -Unique))
#load the configuration for each xpath
if (($result.FilterList | Measure-Object).Count -gt 0) {
Get-WebConfiguration -PSPath "IIS:Sites$SiteName$AppName" -Filter $result.FilterList | Out-Null
}
$result.IsValid=$true
}
catch [System.Exception]
{
$result.Add("Exception",$_.Exception)
}
finally
{
write-output ([PSCustomObject]$result)
}
}#process
}#function Test-IISWebAppConfigIsValid
'myapp1','myapp2' | Test-IISWebAppConfigIsValid |ft -Property AppName,FileExists,IsValid,Exception -AutoSize

输出:

AppName FileExists IsValid Exception                                                                                                                                  
------- ---------- ------- ---------                                                                                                                                  
myapp1        True   False System.Runtime.InteropServices.COMException (0x800700B7): Filename: \?C:inetpubwwwrootmyapp1web.config...                               
myapp2        True    True                                                                                                                                            

最新更新