Saving an XML file in powershell requires complete path. Why?

I am using the XML capabilities of powershell to modify a .config file. Calling XMLDocument.Save doesn't have any effect, unless I supply the complete path name.

# Open the xml file
$config = [xml](get-content web.config)
#
# modify the XML
$config.SelectNodes("./configuration/connectionStrings/add[@name='LocalSqlServer']") | % { $connNode = $_ }
$connNode.connectionString = $connNode.connectionString -replace '^(.*)Server=[^;]+(.*)$', '$1Server=192.168.5.2$2'
#
#
# Now I save it again
#
# This doesn't save it!
$config.Save("web.config");
# However, this works
$config.Save("{0}\\web.config" -f (get-location));

Why doesn't $config.Save("web.config") work?

Did I end up saving it somewhere else, other than my local directory?


Solution 1:

The reason is because the current working directory in powershell isn't necessarly the same as the process working directory.

This is because the powershell working direction ( Get-Location ) can make use of the different filesystem providers - such as the Registry or Certificates. Also because powershell can have multiple runspaces, each one can have their own current working directory.

There are two workarounds to this.

One is to use Resolve-Path (Resolve-Path "orders.xml"), although this will check existence prior to returning the value, so for creation of new files, this may be an issue. The other option is to use the alias of get-location : $pwd for instance ("$pwd\orders.xml")

So for your example you could either change line 2 to be

$config = [xml](get-content (Resolve-Path "web.config"))

or

$config = [xml](get-content "$pwd\web.config")

and respectivly line 12 to be

$config.Save((Resolve-Path "web.config"));

or

$config.Save("$pwd\web.config");

Solution 2:

If it didn't go to the current working directory, I'd check $home.