如果不存在,如何使用 powershell 将 assemblyBinding bindingRedirect 添加到 web.config 或 app.config

How do I add assemblyBinding bindingRedirect to web.config or app.config using powershell if does not exist

我正在使用 PowerShell 自定义部署,我需要手动检查 web.config 是否存在特定的 bindingRedirect对于程序集,我需要添加它以防它不存在。

我找到了很多示例 material 但我很难同时检测绑定重定向是否存在以及创建具有嵌套节点和属性的实际元素。

网络配置(相关部分):

<configuration>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
        <dependentAssembly>
            <assemblyIdentity name="System.Linq" publicKeyToken="B03F5F7F11D50A3A" culture="neutral"/>
            <bindingRedirect oldVersion="0.0.0.0-4.1.2.0" newVersion="4.1.2.0"/>
        </dependentAssembly>
        <dependentAssembly>
            <assemblyIdentity name="System.IO" publicKeyToken="B03F5F7F11D50A3A" culture="neutral"/>
            <bindingRedirect oldVersion="0.0.0.0-4.1.2.0" newVersion="4.1.2.0"/>
        </dependentAssembly>
    </assemblyBinding>
  </runtime>
</configuration>

我试过了:

$XML.SelectSingleNode("/configuration/runtime/assemblyBinding[@xmlns='urn:schemas-microsoft-com:asm.v1']/dependentAssembly/assemblyIdentity[@name='System.IO']")

$XML.configuration.runtime.assemblyBinding.dependentAssembly.SelectSingleNode("assemblyIdentity[@name='System.IO']")

Select-Xml -Xml $XML -XPath '//assemblyIdentity[@name="System.IO"]'
上面的

None 用于获取要在 if 语句中使用的元素。

经过几个小时的尝试和阅读,我发现查找的主要问题是无法以纯文本形式指定的命名空间,更糟的是可以忽略。 对于要添加为子节点的新元素的生成,我首先尝试使用元素属性设置等创建方法,但我的意图并没有成功,而且不是很干净。 所以我终于想到我可以从字符串创建一个XML并将其转换为一个节点,使代码更简单和清晰。

这是我的发现:

[xml]$XML = Get-Content -Path $File -Raw
$ns = New-Object System.Xml.XmlNamespaceManager($XML.NameTable)
$ns.AddNamespace("d", $xml.configuration.runtime.assemblyBinding.NamespaceURI)

if (-not ($XML.SelectSingleNode("//d:assemblyIdentity[@name='Microsoft.Extensions.Logging.Abstractions']", $ns))) {
    $loggingElement = [xml]@'
<dependentAssembly xmlns="urn:schemas-microsoft-com:asm.v1">
  <assemblyIdentity name="Microsoft.Extensions.Logging.Abstractions" publicKeyToken="adb9793829ddae60" culture="neutral" />
  <bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
</dependentAssembly>
'@
    $XML.configuration.runtime.assemblyBinding.AppendChild($XML.ImportNode($loggingElement.dependentAssembly, $true))
}
$XML.Save($File)

阅读 XML 文件后,我创建了一个命名空间,并在 SelectSingleNode 中使用它。 验证绑定重定向不存在后,我从字符串创建一个新的 XML 并在将其作为节点导入后将其附加为子节点。

用于查找迄今为止我的最佳解决方案的最相关链接:

Powershell: XPath cannot select when element has "xmlns" tag?

https://mrlynchbi.wordpress.com/2014/04/02/powershell-and-xml-with-namespaces

https://docs.microsoft.com/en-us/dotnet/standard/data/xml/xpath-queries-and-namespaces

注意:这绝对不是推荐的管理绑定重定向的标准方法,但在我的例子中,我使用了第三方应用程序,它以 zip 更新的形式发布,并通过部署自动化覆盖了默认web.config根据我的需要。