PowerShell XML Manipulation Issue

Utildayael

Ars Tribunus Angusticlavius
7,324
Hello!

I've been trying to put a small script together to build out XML config files for a product at work. While you can edit the file by hand and file in all the blanks, its pretty big and error-prone. I figure if I just prompt the user for the items [or feed with a csv] it'd make life easier. I got most of it working.

Code is not too crazy. Load a template file and feed the variables into the elements. I'm doing the dot notation format which seemed easy enough. The one problem I have is elements that have multiple uh, sub-elements? I can address them to get it to spit out their value but if I try to set it, it wont set. No errors, just does nothing.

Example XML snippet:

XML:
<Gateway>x.x.x.x</Gateway>
<DNS>
          <DNSServers>
             <Server>x.x.x.x</Server>
             <Server>x.x.x.x</Server>
        </DNSServers>
        <DNSDomain>someDomain</DNSDomain>
        <SearchDomains>
             <SearchDomainSuffix>someDomain</SearchDomainSuffix>
        </SearchDomains>
</DNS>


I can call out like:

$xmldoc.DeploymentConfigurations.DeploymentConfiguration.HostManagement.Gateway = "x.x.x.x"

and that works fine

For say, DNSServers tho I can call out:

$xmldoc.DeploymentConfigurations.DeploymentConfiguration.HostManagement.DNS.DNSServers.Server[0]

and it will echo the value from the file properly but if I put = "x.x.x.x" it just never sets it.

How do I address that scenario?

Thanks!
 

ShuggyCoUk

Ars Tribunus Angusticlavius
9,975
Subscriptor++
Are you trying to edit the file or overwrite it entirely each time (the former for example would imply trying to retain formatting/comments, the latter likely not)

If you're trying to do the former I wouldn't do it in powershell (it might be possible, but likely miserable and not much help online).

If the latter then read the file into an object like you are already doing. Edit the document in memory, like you are doing. Then save the edited object back to a (at first) new file to check your edits were right. then swap those two files out (or do an overwrite directly if you're confident, though I would retain a backup of the old file)
 

Utildayael

Ars Tribunus Angusticlavius
7,324
I'm pulling entire XML into an XML object and trying to edit it in memory and save it out to a new file. I just can't get it to handle the nested elements like in my example. :( Code below if it helps for how I am loading the file into

Code:
$outpath = "C:\xxxxxx\config.xml"
[xml]$xmlDoc = New-Object System.Xml.XmlDocument
[xml]$xmldoc = Get-Content '.\template.xml'

#HostManagement - ESX Host
$xmldoc.DeploymentConfigurations.DeploymentConfiguration.HostManagement.Uplink = $gigMAC
$xmldoc.DeploymentConfigurations.DeploymentConfiguration.HostManagement.IPAddress = $ESXmgmtIP
$xmldoc.DeploymentConfigurations.DeploymentConfiguration.HostManagement.Netmask = $ESXmgmtSubnet
$xmldoc.DeploymentConfigurations.DeploymentConfiguration.HostManagement.Gateway = $ESXmgmtGW
$xmldoc.DeploymentConfigurations.DeploymentConfiguration.HostManagement.DNS.DNSServers.Server[0] = $dnsServer1
$xmldoc.DeploymentConfigurations.DeploymentConfiguration.HostManagement.DNS.DNSServers.Server[1] = $dnsServer2
$xmldoc.DeploymentConfigurations.DeploymentConfiguration.HostManagement.DNS.DNSDomain = $dnsDomain
$xmldoc.DeploymentConfigurations.DeploymentConfiguration.HostManagement.DNS.SearchDomains.SearchDomainSuffix = $dnsDomain

$xmldoc.Save($outpath)


LIke I said, I can get it to echo the value out for the two DNSServers nodes but I can't change them which is just weird. Command runs but if I echo it again [or write the file out] it is still the old value. :(

Thanks
 
Last edited:

ShuggyCoUk

Ars Tribunus Angusticlavius
9,975
Subscriptor++
Yeah. it's because the mapping from "array" (or similar linear structure) to xml is fundamentally messy concept and the magic falls down in parts.

This will fix it:
Code:
$xmldoc.DeploymentConfigurations.DeploymentConfiguration..HostManagement.DNS.DNSServers.ChildNodes.Item(0).'#text' = $dnsServer1

I worked it out from this question and answer

Incidentally this is my biggest problem with XML. It failed to provide a canonical and clean way to described lists/arrays. That's so foundational to so much of modern computing the discrepancy is palpable almost every time I have to crowbar them in when you cross a boundary of expectations in behaviour
 
  • Like
Reactions: Utildayael

Paul Hill

Ars Legatus Legionis
19,878
Incidentally this is my biggest problem with XML. It failed to provide a canonical and clean way to described lists/arrays. That's so foundational to so much of modern computing the discrepancy is palpable almost every time I have to crowbar them in when you cross a boundary of expectations in behaviour
XML does support lists as long as you don't mind whitespace as a separator

<DnsServers>x.x.x.x x.x.x.x x.x.x.x</DnsServers> would be expressible in XSD
 

ShuggyCoUk

Ars Tribunus Angusticlavius
9,975
Subscriptor++
It "supports" in a myriad different ways, none always consistent, that's basically not actually supporting it as a interchange format, only as a round trip serialisation format within an eco system (which is often fine, it's just not the same thing and you realise how it's not when things fall apart because someone didn't understand the limitations).

Contrast to JSON, YAML etc