Skip to content


Subversion checkout URL

You can clone with
Download ZIP
A nicer way to edit xml files from powershell
Fetching latest commit...
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.
specs fixing powershell qq "WARNING: Some imported command names contain on…
LICENSE.txt adding license
PSUpdateXml.psm1 fixing powershell qq "WARNING: Some imported command names contain on…


Editing XML from powershell has always seemed harder than it should be.  Maybe I am missing some article..  Reading XML is fairly easy, I like I can cast a string to XML.  I think changing an XML file should be as easy.  I think this module makes that true (if you don't mind XPATH).  It is simple code to rewrite on a project basis, but I figure it's worth writing once with tests.

See the "specs" folder to see specifics on how to use PSUpdateXML.psm1.

  update-xml [System.IO.FileInfo]xmlFile [ScriptBlock]action
    - Runs $action against $xmlFile.  $action can in turn call set-xml, for-xml, etc to modify that XML file.
  Every other function is called within the script block passed to update-xml.  All calls taking XPATH expression are interpreted relative the current node.  
  for-xml [QUANTIFIER] [string]xpath [ScriptBlock]action
    Iterates over every node matching xpath.  Calls action with the current node as that matching node.
  set-xml [QUANTIFIER] [string]xpath [string]value
    Sets the xml tag or attribute value at the xpath location.
  get-xml [QUANTIFIER] [string]xpath
    Returns the xml tag or attribute value at the xpath location
  remove-xml [QUANTIFIER] [string]xpath
    Removes tags or attributes at the xpath location.
  append-xml [QUANTIFIER] [string]xpath [string]value
    Appends the text as XML after the last child of the current node.
  add-xmlnamespace [string]name [string]value
    - Allow a namespace be specified in your XPATH expressions
    - If you can't get your XPATH to match, it may be the namespace..
    - reference:

  QUANTIFIER: optionally use -exactlyOnce, -atLeastOnce, or -atMostOnce

Sample usage (update-xml, set-xml, append-xml):

    import-module .\PSUpdateXml.psm1  # this is the only file you need to deploy, everything else in the project path is for testing

    $webConfigFilepath = (join-path (join-path $stagingDirectory "WebAppProjectName") "web.config");

    cp $webConfigFilepath "$webConfigFilepath.backup"

    update-xml $webConfigFilepath {

        #(deployment information is already initialized to $deploy)

        set-xml -exactlyOnce "//configuration/system.web/compilation/@debug" $deploy.debug

        @("SiteName", "BaseUrl", "CdnUrl", "AdminUsername", "AdminPassword", "AddonPath", 
            "NoReplySiteEmail", "AllowUnsafeHooks", "SmtpHost", "SmtpPort", "RavenPath") | % {

            set-xml -exactlyOnce "//configuration/applicationSettings/*/setting[@name='$($_)']/value" $deploy[$_]

        foreach ($connectionString in $deploy.connectionStrings.keys) {

            $connectionStringValue = $deploy.connectionStrings[$connectionString];

            append-xml -exactlyOnce "//configuration/connectionStrings" "<add name=`"$connectionString`" connectionString=`"$connectionStringValue`"/>"

        if ($deploy.elmahConfiguration) {
            set-xml "//configuration/elmah" $deploy.elmahConfiguration
To run the tests, run .\Psake.ps1 from powershell.
Something went wrong with that request. Please try again.