【问题标题】:add elements with multiple values to existing xml file using powershell使用 powershell 将具有多个值的元素添加到现有的 xml 文件
【发布时间】:2019-05-22 15:38:30
【问题描述】:

我正在自动化 SQL 报告服务,我需要将代理设置添加到 web.config 文件。我尝试在 powershell 中执行此操作,但我无法弄清楚如何通过 powershell 执行此操作。

我需要将以下 xml 代码添加到现有 web.config XML 文件的末尾

  <system.net>
    <defaultProxy enabled="true" useDefaultCredentials="true">
      <proxy bypassonlocal="True" proxyaddress="http://ocs.kennisnet.nl:3128" />
    </defaultProxy>
  </system.net>

完整的xml文件需要是:

<configuration>
  <system.web>
    <pages validateRequest="false">
      <controls>
        <add tagPrefix="asp" namespace="System.Web.UI" assembly="System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
      </controls>
      <namespaces>
        <remove namespace="System.Linq" />
        <remove namespace="System.ComponentModel.DataAnnotations" />
      </namespaces>
    </pages>
    <authentication mode="Windows" />
    <identity impersonate="true" />
    <compilation defaultLanguage="c#" debug="false" targetFramework="4.0" tempDirectory="E:\Program Files\Microsoft SQL Server Reporting Services\SSRS\ReportServer\RSTempFiles">
      <assemblies>
        <clear />
        <add assembly="ReportingServicesWebServer" />
        <add assembly="System.Xml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
        <add assembly="System.Web.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
        <add assembly="System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
        <add assembly="System.Xml.Linq, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
        <add assembly="System.Web.DynamicData, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
      </assemblies>
    </compilation>
    <trace enabled="false" requestLimit="10" pageOutput="false" traceMode="SortByTime" localOnly="true" />
    <sessionState mode="Off" />
    <httpHandlers>
      <add verb="*" path="Reserved.ReportServer" type="Microsoft.ReportingServices.WebServer.ReportServiceHttpHandler, ReportingServicesWebServer" />
      <add verb="*" path="Reserved.ReportViewerWebControl.axd" type="Microsoft.Reporting.WebForms.HttpHandler, ReportingServicesWebServer, Version=14.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91" />
      <add verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" validate="false" />
    </httpHandlers>
    <httpModules>
      <clear />
      <add name="OutputCache" type="System.Web.Caching.OutputCacheModule" />
      <add name="WindowsAuthentication" type="System.Web.Security.WindowsAuthenticationModule" />
      <add name="FormsAuthentication" type="System.Web.Security.FormsAuthenticationModule" />
      <add name="PassportAuthentication" type="System.Web.Security.PassportAuthenticationModule" />
      <add name="RoleManager" type="System.Web.Security.RoleManagerModule" />
      <add name="UrlAuthorization" type="System.Web.Security.UrlAuthorizationModule" />
      <add name="FileAuthorization" type="System.Web.Security.FileAuthorizationModule" />
      <add name="AnonymousIdentification" type="System.Web.Security.AnonymousIdentificationModule" />
      <add name="Profile" type="System.Web.Profile.ProfileModule" />
      <add name="ErrorHandlerModule" type="System.Web.Mobile.ErrorHandlerModule, System.Web.Mobile, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
    </httpModules>
    <globalization requestEncoding="utf-8" responseEncoding="utf-8" />
    <httpRuntime executionTimeout="9000" requestValidationMode="2.0" />
    <securityPolicy>
      <trustLevel name="RosettaSrv" policyFile="rssrvpolicy.config" />
    </securityPolicy>
    <trust level="RosettaSrv" originUrl="" legacyCasModel="true" />
    <webServices>
      <soapExtensionTypes>
        <add type="Microsoft.ReportingServices.WebServer.RsSoapExtension, ReportingServicesWebServer" priority="1" group="1" />
      </soapExtensionTypes>
      <soapExtensionReflectorTypes>
        <add type="Microsoft.ReportingServices.WebServer.RsSoapExtensionReflector, ReportingServicesWebServer" />
      </soapExtensionReflectorTypes>
    </webServices>
  </system.web>
  <runtime>
    <alwaysFlowImpersonationPolicy enabled="true" />
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="Microsoft.ReportingServices.Interfaces" publicKeyToken="89845dcd8080cc91" culture="neutral" />
        <bindingRedirect oldVersion="8.0.242.0-14.0.0.0" newVersion="14.0.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="Microsoft.ReportingServices.ProcessingCore" publicKeyToken="89845dcd8080cc91" culture="neutral" />
        <bindingRedirect oldVersion="9.0.242.0-14.0.0.0" newVersion="14.0.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="Microsoft.ReportingServices.ProcessingObjectModel" publicKeyToken="89845dcd8080cc91" culture="neutral" />
        <bindingRedirect oldVersion="9.0.242.0-14.0.0.0" newVersion="14.0.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="Microsoft.SqlServer.Types" publicKeyToken="89845dcd8080cc91" culture="neutral" />
        <bindingRedirect oldVersion="10.0.0.0-14.0.0.0" newVersion="14.0.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="msmgdsrv" publicKeyToken="89845dcd8080cc91" />
        <bindingRedirect oldVersion="9.0.0.0-14.0.0.0" newVersion="14.0.0.0" />
        <codeBase version="14.0.0.0" href="%ProgramFiles%\Microsoft Analysis Services\AS OLEDB\140\msmgdsrv.dll" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="Microsoft.Owin" publicKeyToken="31bf3856ad364e35" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="System.Web.Cors" publicKeyToken="31bf3856ad364e35" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-5.0.0.0" newVersion="5.2.3.0" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
  <system.net>
    <defaultProxy enabled="true" useDefaultCredentials="true">
      <proxy bypassonlocal="True" proxyaddress="http://ocs.kennisnet.nl:3128" />
    </defaultProxy>
  </system.net>
</configuration>

我发现了很多代码示例,但似乎都没有工作,我设法创建了波纹管代码,但它没有保存文件,而且我不知道如何添加第二个键值。希望你们中的一个人比我更熟练..

$file="web.config"
[xml]$xmlDoc = [System.Xml.XmlDocument](Get-Content $file)

$newEl=$xmlDoc.CreateElement("system.net")
$xmlDoc.configuration.AppendChild($newEl)  
$xmlDoc.Save($file)

$newEl=$xmlDoc.CreateElement("defaultProxy")   
$nameAtt1=$xmlDoc.CreateAttribute("enabled")
$nameAtt1.psbase.value="true"  
$newEl.SetAttributeNode($nameAtt1)  

$nameAtt2=$xmlDoc.CreateAttribute("useDefaultCredentials")  
$nameAtt2.psbase.value="true"    
$newEl.SetAttributeNode($nameAtt2) 
$xmlDoc.configuration["system.net"].AppendChild($newEl)  

$xmlDoc.Save($file)

最终的结果需要创建完整的XML文件如上图。

请帮忙...

【问题讨论】:

    标签: xml powershell


    【解决方案1】:

    以下将在运行时元素之后插入新的 XML 数据:

    $webconfig = [xml](Get-Content C:\temp\web.config)
    $newxml = [xml](Get-Content c:\temp\new.xml)
    
    $newNode = $webconfig.ImportNode($newxml.'system.net',$true)
    $InsertAfterNode = $webconfig.configuration.runtime
    $null = $webconfig.configuration.insertAfter($newNode,$InsertAfterNode)
    $webconfig.Save("c:\temp\web.config")
    

    $newNode 存在,因此我们拥有InsertAfter() 方法的正确对象类型。对应的ImportNode()方法输出我们想要的对象类型。传递了$true,以便我们导入system.net 的所有后代元素。

    我在处理文件时使用了完整路径。我相信.Save() 方法通常需要完整路径,因为它默认为特定目录。请注意,这不是通用代码,它依赖于您专门提供要插入新数据的元素。

    【讨论】:

      【解决方案2】:

      还有一种使用 XElement 的方法。

      using namespace "System.Xml.Linq"
      Add-Type -AssemblyName System.Xml.Linq
      
      $configPath = Convert-Path "web.config"
      $newElement = [XElement]@'
        <system.net>
          <defaultProxy enabled="true" useDefaultCredentials="true">
            <proxy bypassonlocal="True" proxyaddress="http://ocs.kennisnet.nl:3128" />
          </defaultProxy>
        </system.net>
      '@
      
      $configuration = [XElement]::Load($configPath)
      $configuration.Add($newElement)
      $configuration.ToString() | Out-File "new.config"
      

      【讨论】:

      • 这似乎是最容易使用的,只需添加我需要添加到 xml 文件的代码块,但是我在加载部分收到以下错误消息:无法找到类型 [ X元素]。在 C:\OneDrive\Kennisnet\Vensters - SODK - DPO - Vensters TMG\scripts\install_sql_reporting\acc\xml_test.ps1:12 char:18 + $configuration = [XElement]::Load($configPath) + ~~~~ ~~~~~~ + CategoryInfo : InvalidOperation: (XElement:TypeName) [], RuntimeException + FullyQualifiedErrorId : TypeNotFound
      • 附言。我在 Windows Server 2016 上使用 powershell 4.0 版运行它。
      【解决方案3】:

      我最终做了以下事情:

      $newXml = @'
        <system.net>
          <defaultProxy enabled="true" useDefaultCredentials="true">
            <proxy bypassonlocal="True" proxyaddress="http://ocs.kennisnet.nl:3128" />
          </defaultProxy>
        </system.net>
      </configuration>
      '@
      
      $File = ".\web.config" 
      
      # Remove last line of file
      $Content = Get-Content $File
      $Output = $Content[0..($Content.count - 2)]
      
      Out-File -FilePath $File -InputObject $Output
      
      # Add code block to file
      Add-Content -Path ".\web.config" -Value $newXml
      

      这不是最好用的东西,因为我假设文件的最后一行总是相同的,但它确实对我有用。

      遗憾的是,我无法按照 rokumaru 的建议使代码工作,因为这将是最好的使用方法,我希望他能补充此代码以使其工作。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-10-22
        • 1970-01-01
        • 1970-01-01
        • 2014-06-27
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多