Update configuration files using PowerShell


 

Hi Readers,

We will see in this post on how we can edit web.config or other configuration files using PowerShell. There are already several posts available on internet which shows this functionality, however I faced difficulties in updating connection string in the configuration file as they are not direct. Below steps will help you in updating the connection strings as well.

Sample configuration file is shown below. Other sections of web.config file are not shown in this blog for simplicity.

 <configuration>
   <connectionStrings>
     <add name="TestDBEntities" connectionString="metadata=res://*/TestProject.csdl|res://*/TestProject.ssdl|res://*/TestProject.msl;provider=System.Data.SqlClient;provider connection string=&quot;data source=SQL01;initial catalog=TestDB;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework&quot;" providerName="System.Data.EntityClient" />
     <add name="TestWebEntities" connectionString="metadata=res://*/TestProject.csdl|res://*/TestProject.ssdl|res://*/TestProject.msl;provider=System.Data.SqlClient;provider connection string=&quot;data source=SQL01;initial catalog=TestWeb;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework&quot;" providerName="System.Data.EntityClient" />
   </connectionStrings>
   <appSettings>
     <add key="SCVMMServerName" value="VMM01" />
     <add key="SCVMMServerPort" value="8100" />
   </appSettings>
</configuration>

We will try to update ‘appSettings’ section and connectionStrings section of this configuration file.

1. Read configuration file in a XML variable

   1: $webConfig = 'C:\inetpub\wwwroot\VMMService\Web.config'
   2: $doc = (Get-Content $webConfig) -as [Xml]

2. Update ‘appSettings’ Section

   1: $obj = $doc.configuration.appSettings.add | where {$_.Key -eq 'SCVMMServerName'}
   2: $obj.value = 'CPVMM02'

3. Add new 'appSetting'. You will need to create an XmlElement and append it as a child node to 'appSettings'

$newAppSetting = $doc.CreateElement("add")
$doc.configuration.appSettings.AppendChild($newAppSetting)
$newAppSetting.SetAttribute("key","SCVMMIPAdress");
$newAppSetting.SetAttribute("value","10.10.10.10");

4. Update ‘connectionStrings’ section. Here is the tweak, you have to read the root element and then modify the connection string as shown below:-

   1: $root = $doc.get_DocumentElement();
   2: $myConString = $root.connectionStrings.add | ? {$_.name -eq 'TestDBEntities'}
   3: $newCon = $myConString.connectionString.Replace('data source=SQL01','data source=SQL02');
   4: $myConString.connectionString = $newCon

5. Save the configuration file

   1: $doc.Save($webConfig)

The combined code will look like below:-

$webConfig = 'C:\inetpub\wwwroot\TestService\Web.config'
$doc = (Get-Content $webConfig) -as [Xml]
$obj = $doc.configuration.appSettings.add | where {$_.Key -eq 'SCVMMServerName'}
$obj.value = 'CPVMM02'

$newAppSetting = $doc.CreateElement("add")
$doc.configuration.appSettings.AppendChild($newAppSetting)
$newAppSetting.SetAttribute("key","SCVMMIPAdress");
$newAppSetting.SetAttribute("value","10.10.10.10");
 
$root = $doc.get_DocumentElement();
$myConString = $root.connectionStrings.add | ? {$_.name -eq 'TestDBEntities'}
$newCon = $myConString.connectionString.Replace('data source=SQL01','data source=SQL02');
$myConString.connectionString = $newCon
 
$doc.Save($webConfig)

The updated XML will contain modified values as shown below:-

<configuration>
 <connectionStrings>
 <add name="TestDBEntities" connectionString="metadata=res://*/TestProject.csdl|res://*/TestProject.ssdl|res://*/TestProject.msl;provider=System.Data.SqlClient;provider connection string=&quot;data source=SQL02;initial catalog=TestDB;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework&quot;" providerName="System.Data.EntityClient" />
 <add name="TestWebEntities" connectionString="metadata=res://*/TestProject.csdl|res://*/TestProject.ssdl|res://*/TestProject.msl;provider=System.Data.SqlClient;provider connection string=&quot;data source=SQL01;initial catalog=TestWeb;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework&quot;" providerName="System.Data.EntityClient" /> 
</connectionStrings>
 <appSettings>
 <add key="SCVMMServerName" value="CPVMM02" />
 <add key="SCVMMServerPort" value="8100" />
 <add key="SCVMMIPAdress" value="10.10.10.10" />
 </appSettings>
</configuration>

Let me know if there are some sections of configuration file which you are finding difficult to update and I will add them here in this blog 🙂 Happy Scripting!!!


Comments (50)

  1. Santosh@CA says:

    Hi Sonam,

    Many thanks for this article. I was really facing this challenge for automating the Web.config Transformation process. Your article really helped me to to tackle that challenge. Awesome..Keep on writing such nice articles.

  2. Sam says:

    I need to edit the below xml file, but could not able to do so… I need to edit only the newVersion value where then name is B… how can i achieve this..

    <?xml version="1.0"?>

    <configuration>

    <runtime>

    <legacyCorruptedStateExceptionsPolicy enabled="true" />

    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">

    <dependentAssembly>

    <assemblyIdentity name="A"

     publicKeyToken="585a888b4a9ba2e3"

     culture="neutral" />

    <bindingRedirect oldVersion="0.0.0.0-65534.65534.65534.65534"

    newVersion="4.0.0.103"/>

    </dependentAssembly>

    <dependentAssembly>

    <assemblyIdentity name="B"

     publicKeyToken="22955931b98512b6"

     culture="neutral" />

    <bindingRedirect oldVersion="0.0.0.0-65534.65534.65534.65534"

    newVersion="4.0.0.103"/>

    </dependentAssembly>

    <dependentAssembly>

    <assemblyIdentity name="C"

     publicKeyToken="4ab506411d17b07e"

     culture="neutral" />

    <bindingRedirect oldVersion="0.0.0.0-65534.65534.65534.65534"

    newVersion="4.0.0.103"/>

    </dependentAssembly>

    </assemblyBinding>

    </runtime>

    </configuration>

  3. Sonam Rastogi says:

    Hi,

    For XML files, please refer this blog :- blogs.msdn.com/…/update-xml-file-using-powershell.aspx

  4. Same says:

    Thank you Sonam for your reply. I need to change newVersion to the number value in whole document wherever newVersion is occuring. Please help. I have gone through your other blog for XML files, but couldnt not succeed.

  5. Sonam Rastogi says:

    Hope this will help. thanks.

    $path = 'C:Users<UserName>DesktopVariable.xml'

    $xml = [xml](Get-Content $path)

    $NewVersionUpdatedValue = 'MyNewVersion'

    $daNodes = $xml.configuration.runtime.assemblyBinding.dependentAssembly

    foreach($node in $daNodes)

    {

       if($node.assemblyIdentity.name -eq 'B')

       {

           $updateNode = $node.bindingRedirect

           $updateNode.newVersion = $NewVersionUpdatedValue

       }

    }

    $xml.Save($path)

  6. Sonam Rastogi says:

    I have also updated the post to consider this scenario. Thanks.

    blogs.msdn.com/…/update-xml-file-using-powershell.aspx

  7. Sam says:

    Many thanks Sonam. For some reason, I am getting this below error when I tried your method. I have changed the script like this…

    $path = 'C:Users<UserName>DesktopVariable.xml'

    $xml = [xml](Get-Content $path)

    $NewVersionUpdatedValue = 'MyNewVersion'

    $NewVersionUpdatedValue2 = 'MyNewVersion2'

    $daNodes = $xml.configuration.runtime.assemblyBinding.dependentAssembly

    foreach($node in $daNodes)

    {

      if($node.assemblyIdentity.name -eq 'A' -or $node.assemblyIdentity.name -eq 'B' -or

      {

          $updateNode = $node.bindingRedirect

          $updateNode.newVersion = $NewVersionUpdatedValue

      }

      if($node.assemblyIdentity.name -eq 'C' -or $node.assemblyIdentity.name -eq 'D' -or

      {

          $updateNode = $node.bindingRedirect

          $updateNode.newVersion = $NewVersionUpdatedValue2

      }

    }

    $xml.Save($path)

    =============================

    Error in powershell:

    Cannot convert value "System.Object[]" to type "System.Xml.XmlDocument". Error: "Name cannot begin with the '<'

    character, hexadecimal value 0x3C. Line 725, position 8."

    At C:UsersakolaDesktoptest2.ps1:2 char:1

    + $xml = [xml](Get-Content $path)

    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

       + CategoryInfo          : InvalidArgument: (:) [], RuntimeException

       + FullyQualifiedErrorId : InvalidCastToXmlDocument

    You cannot call a method on a null-valued expression.

    At C:UsersakolaDesktoptest2.ps1:13 char:1

    + $xml.Save($path)

    + ~~~~~~~~~~~~~~~~

       + CategoryInfo          : InvalidOperation: (:) [], RuntimeException

       + FullyQualifiedErrorId : InvokeMethodOnNull

    ================================

  8. Sam says:

    by the way… its a config file but xml file

  9. Sam says:

    I am so sorry…i am so messed up with this frustration today…  correction… its a config file but not the xml file…

  10. Sonam Rastogi says:

    Hi,

    Given below config file saved as 'MyConfig.config'

    <?xml version="1.0"?>

    <configuration>

     <runtime>

       <legacyCorruptedStateExceptionsPolicy enabled="true" />

       <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">

         <dependentAssembly>

           <assemblyIdentity name="A" publicKeyToken="585a888b4a9ba2e3" culture="neutral" />

           <bindingRedirect oldVersion="0.0.0.0-65534.65534.65534.65534" newVersion="4.0.0.0" />

         </dependentAssembly>

         <dependentAssembly>

           <assemblyIdentity name="B" publicKeyToken="22955931b98512b6" culture="neutral" />

           <bindingRedirect oldVersion="0.0.0.0-65534.65534.65534.65534" newVersion="4.0.0.0" />

         </dependentAssembly>

         <dependentAssembly>

           <assemblyIdentity name="C" publicKeyToken="4ab506411d17b07e" culture="neutral" />

           <bindingRedirect oldVersion="0.0.0.0-65534.65534.65534.65534" newVersion="4.0.0.0" />

         </dependentAssembly>

       </assemblyBinding>

     </runtime>

    </configuration>

    This PowerShell code works absolutely fine.

    $path = 'C:MyConfig.config'

    $xml = [xml](Get-Content $path)

    $NewVersionUpdatedValue = 'MyNewVersion'

    $NewVersionUpdatedValue2 = 'MyNewVersion2'

    $daNodes = $xml.configuration.runtime.assemblyBinding.dependentAssembly

    foreach($node in $daNodes)

    {

      if($node.assemblyIdentity.name -eq 'A' -or $node.assemblyIdentity.name -eq 'B')

      {

          $updateNode = $node.bindingRedirect

          $updateNode.newVersion = $NewVersionUpdatedValue

      }

      elseif($node.assemblyIdentity.name -eq 'C' -or $node.assemblyIdentity.name -eq 'D')

      {

          $updateNode = $node.bindingRedirect

          $updateNode.newVersion = $NewVersionUpdatedValue2

          break

      }

    }

    $xml.Save($path)

    The final Config will look like below:-

    <?xml version="1.0"?>

    <configuration>

     <runtime>

       <legacyCorruptedStateExceptionsPolicy enabled="true" />

       <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">

         <dependentAssembly>

           <assemblyIdentity name="A" publicKeyToken="585a888b4a9ba2e3" culture="neutral" />

           <bindingRedirect oldVersion="0.0.0.0-65534.65534.65534.65534" newVersion="MyNewVersion" />

         </dependentAssembly>

         <dependentAssembly>

           <assemblyIdentity name="B" publicKeyToken="22955931b98512b6" culture="neutral" />

           <bindingRedirect oldVersion="0.0.0.0-65534.65534.65534.65534" newVersion="MyNewVersion" />

         </dependentAssembly>

         <dependentAssembly>

           <assemblyIdentity name="C" publicKeyToken="4ab506411d17b07e" culture="neutral" />

           <bindingRedirect oldVersion="0.0.0.0-65534.65534.65534.65534" newVersion="MyNewVersion2" />

         </dependentAssembly>

       </assemblyBinding>

     </runtime>

    </configuration>

  11. Sam says:

    Thanks a bunch !!….  It works perfectly fine without any issues… Thanks again !!

    1. I am glad it helped.

  12. Jonas says:

    Hi!

    Thank you for the great guide, however, I cannot seem to apply it to my problem.

    I want to add a DbProvider under DbProviderFactories in System.data. How can do I proceed?

  13. Sonam Rastogi says:

    Please Share the sample input and output config file.

  14. Anonymous says:

    Nice Article..

  15. r.ranjan says:

    Great Article. Helped a lot.

  16. Bernd says:

    How do you update the "data source" when you do not know its value? That would be worth a post!

  17. When you update – there is always an old value and a new value. You will always be aware of the new value to be updated. The value can be direct or can be read through some file or database.

  18. AKSHAY says:

    Hi sonam, Thanks for the post. It helped alot. I have a query as i am automating the whole deployment process , i dont want use hard coded path in the script. Is there any way to to assign the values to new variable using the priviously declared variables. EG. $servicepath has the path where the service is installed. I want assign the same path to a new variable to edit the config.

  19. Hi Akshay,

    You can do $webConfig = $servicePath in your script.

  20. Akshay says:

    Hey Sonam,

    already tried that. Actually it was the Scope of the variable that was creating trouble. Resolved it for now,the other thing that is troubling me now is i need to run the .bat file which installs the service. My code for it is:

    $command = {

    cd "$using:installpath$using:servicename"

    ./Installer.bat

    }

    Invoke-Command -Session $mysession1 -ScriptBlock $command

    "<b>The error I get is: The term './Installer.bat' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was

    included, verify that the path is correct and try again."</b>

    can you help on how to run a .bat file?

    Thanks (in advance)

  21. Please try Start-Process cmdlet

  22. sandhya says:

    Thanks a lot for this article. I have to edit my below connection string in an automated process.

    I had followed your article and edited the powershell script like this:
    1: $webConfig = ‘C:\inetpub\wwwroot\TestService\Web.config’
    2: $doc = (Get-Content $webConfig) -as [Xml]
    5:
    6: $root = $doc.get_DocumentElement();
    7: $newCon = $root.connectionStrings.add.connectionString.Replace(‘data source=10.0.1.4′,’data source=accdbsrv24.database.windows.net,1433′,’initial catalog=AdventureWorks’,’initial catalog=accdb24′,’Uid=sa’,Uid=’sandhya’,’Password=demo@pass1′,’Password=mama@12345′);
    8: $root.connectionStrings.add.connectionString = $newCon
    10: $doc.Save($webConfig)

    Please guide me, is it correct or wrong?

    1. replied in another message below.

  23. sandhya says:

    Thanks a lot for this article. I have to edit my below connection string in an automated process.

    I had followed your article and edited the powershell script like this:
    1: $webConfig = ‘C:\inetpub\wwwroot\cloudshop\Web.config’
    2: $doc = (Get-Content $webConfig) -as [Xml]
    5:
    6: $root = $doc.get_DocumentElement();
    7: $newCon = $root.connectionStrings.add.connectionString.Replace(‘data source=10.0.1.4′,’data source=accdbsrv24.database.windows.net,1433′,’initial catalog=AdventureWorks’,’initial catalog=accdb24′,’Uid=sa’,Uid=’sandhya’,’Password=demo@pass1′,’Password=mama@12345′);
    8: $root.connectionStrings.add.connectionString = $newCon
    10: $doc.Save($webConfig)

    Please guide me, is it correct or wrong?

    1. Hi Sandhya,

      The syntax that you have used is wrong in replace method.
      It should be .Replace(‘old value’,’new value’)

      Below should work for you :-
      $newCon = $root.connectionStrings.add.connectionString.Replace(‘data source=SQL01;initial catalog=TestDB;integrated security=True′,’data source=accdbsrv24.database.windows.net,1433,initial catalog=AdventureWorks,initial catalog=accdb24,Uid=sa,Uid=sandhya,Password=demo@pass1′);

      1. Iyyappan says:

        Hi,

        This logic worked for me, but I am facing an issue like when I am saving the XML with $doc.save(“File path”), It is changing the &qout; into double qoutes (“), How to prevent it?.

        1. Please provide sample code and file.

          1. Vikash says:

            Hello Sonam,
            I want to add 1 more key under appSettings sections, how can I do that, I want my xml file to be like

            An early help will be highly appreciable

            thanks
            Vikash

          2. I have updated the blog post and have added section on how to add a new key under ‘appSettings’ section.

  24. ona says:

    Hi
    How do i pass the value from command line to $obj.value = ‘CPVMM02’, I tried
    ./scriptfile

    1. Hi Ona, Please refer this article.

      https://technet.microsoft.com/en-us/magazine/jj554301.aspx

      you will need to define parameters in the powershell script and then you will be able to pass parameters through command line while calling the script.

  25. Ravi says:

    Hi Sonam,
    Thanks for posting this article. I need some help from your end in editing the following config file using PowerShell. In the following XML, I need to drop all the attributes and their corresponding values in the objectstorage and insert three brand new attributes and their corresponding values. Could you please let me know, how I can achieve this task.

    1. Hi Ravi, this blog may help you
      https://blogs.msdn.microsoft.com/sonam_rastogi_blogs/2014/05/14/update-xml-file-using-powershell/

      Information is available on how to add new attributes to a node.

  26. kantharao says:

    Super it is updating config values.Thanks a lot.

  27. Sree says:

    Hi Sonam,

    Thanks for the article. I have a question. What if we have multiple config files in a project where we need to update appSettings all at a time? Is there any other way to update appSettings, instead of doing it for every single file?

    1. Hi Sree, if you are using a C# application, then you can use ConfigurationManager.AppSettings property

  28. jayashri says:

    Hi Sonal, I want add entry to web.config for end point to get connect with biztalk server, at below section :

    which is multiline section :

    REquest you to help me in this.

    1. Adding a new section is already described in Point 3 in above post

  29. sagar says:

    Hi Sonal, could you please help on the below script, as i am trying to edit connectionstring xml file, as its giving error(You cannot call a method on a null-valued expression.). Please find the below script:

    $connectionStringsconfig = ‘C:s3connectionStrings.config’
    $doc = (Get-Content $connectionStringsconfig) -as [Xml]
    $root = $doc.get_DocumentElement();
    $newCon = $root.connectionStrings.add.connectionString.Replace(‘data source=core-db-1.core.vpc.me’,’data source=core-core-db-2.core.vpc.me’);
    $root.connectionStrings.add.connectionString = $newCon
    $doc.Save($webConfig)

    1. Make sure the structure of your config file is same as mentioned in this post
      Hierarchy should be configuration->connectionStrings->add

      Debug and see what values you are getting in $root and $newCon variables
      Please post your config file here for further help.

  30. Nilesh Chaubey says:

    Hi Sonam,

    I want implement Web.config transformation using Powershell Script like I have two files at different-different location “Web.config” and another file “Temp.Web.Config” , i want to read the Web.config file Keys and replace the value of that particular key with Temp.Web.Config file value.

    Suppose I have 10 tag in Temp.Web.Config file and Web.Config have more than 100 tag , I want to search only 10 tag in web.config file and replaced with the Temp.Web.config value, Please help me to achieve this.

    1. Hi Nilesh,

      You will be required to find the exact nodes you would like to replace and then write logic to update the node values.
      Some examples similar to this can be found on this blog:
      https://blogs.msdn.microsoft.com/sonam_rastogi_blogs/2014/05/14/update-xml-file-using-powershell/

  31. Ben says:

    Hi Sonam,
    This code is exactly what I’ve been searching for, however I’m getting the following error “The property ‘connectionString’ cannot be found on this object. Verify that the property exists and can be set.” My web.config has multiple entries in the connection strings – which I think is the cause of the error, as your code throws the same error if I add an extra entry to your sample xml.
    ie.

    Any ideas on working with the multiple entries?

    1. Hi Ben, Thanks for the feedback. I have updated this blog to handle multiple ConnectionStrings.

      You basically need to search for the exact ConnectionString based on Name.

  32. Sooraj says:

    I have and AD user account the password of which needs to be updated automatically in the config.properties file whenever it changes need help in this.

    1. You may need to monitor the AD account on a regular basis and when any change is recognized, this Powershell script to update config file will be triggered.

  33. Sammy says:

    Hi Sonam,

    Thank you so much for this wonderful article. This saved me from doing changes on tons of machine. However, there is an issue I’m facing and unable to resolve it.

    Let’s say this is my connectionString which I’m trying to edit using powershell

    $obj.connectionString = “metadata=res://*/Cex.Store.Data.EntityFramework.Entities.StoreMYSQLModel.csdl|res://*/Cex.Store.Data.EntityFramework.Entities.StoreMYSQLModel.ssdl|res://*/Cex.Store.Data.EntityFramework.Entities.StoreMYSQLModel.msl;provider=Devart.Data.MySql;provider connection string="User Id=someId;Password=pswrd;Host=hostname;Database=db;Unicode=true;pooling=false;Persist Security Info=True"”

    When I use the above command to edit the machine config, it changes the & (ampersand) sign to & because of which I’m not able to proceed further. I looked up on the internet and tried many different ways of escaping & but it seems like the machine.config is doing the changes and not powershell. Can you please help me with this?

    After doing the changes, it looks like this:

    “metadata=res://*/Cex.Store.Data.EntityFramework.Entities.StoreMYSQLModel.csdl|res://*/Cex.Store.Data.EntityFramework.Entities.StoreMYSQLModel.ssdl|res://*/Cex.Store.Data.EntityFramework.Entities.StoreMYSQLModel.msl;provider=Devart.Data.MySql;provider connection string=&quot;User Id=someId;Password=pswrd;Host=hostname;Database=db;Unicode=true;pooling=false;Persist Security Info=True&quot;”

    1. Your initial connectionString in config file should contain &quot instead of ”

      Check connectionString property of ‘TestDBEntities’ in example below:

      connectionString=”metadata=res://*/TestProject.csdl|res://*/TestProject.ssdl|res://*/TestProject.msl;provider=System.Data.SqlClient;provider connection string="data source=SQL01;initial catalog=TestDB;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework"”

Skip to main content