1
votes

I have an xml file (CSCFG File) like below

XML File:

 <Role name="Role1">
    <Instances count="2" />
    <ConfigurationSettings>
      <Setting name="Key1" value="123456" />
      <Setting name="Key2" value="1234567890" />
      <Setting name="Key3" value="true" />
    </ConfigurationSettings>
    <Certificates>
    </Certificates>
  </Role>

I need to add multiple certificate elements inside certificates node.

To be XML:

<Role name="Role1">
    <Instances count="2" />
    <ConfigurationSettings>
      <Setting name="Key1" value="123456" />
      <Setting name="Key2" value="1234567890" />
      <Setting name="Key3" value="true" />
    </ConfigurationSettings>
    <Certificates>
      <Certificate name="certificate1" thumbprint="12345678" />
      <Certificate name="certificate2" thumbprint="01234567" />
      <Certificate name="certificate3" thumbprint="09876543" />
    </Certificates>
  </Role>

I am trying to do it with the below code

$xmlDoc = [System.Xml.XmlDocument](Get-Content $configFile);
$xmlDoc.Role.Certificates.AppendChild($xmlDoc.CreateElement("Certificate"));
$newXmlCertificate.SetAttribute(“name”,$certName);
$newXmlCertificate.SetAttribute(“thumbprint”,$CertThumbprint);
$xmlDoc.save($configFile)

This is the exceptions am getting while doing it: Method invocation failed because [System.String] does not contain a method named 'AppendChild'.

Please help me out.

2
Why was this question voted down?? If the reader does not know the answer, will it be voted down ??Pradebban Raja
I'm not sure why this got voted down except for maybe your title isn't a question. Try rewording it into the form of a question How do you add an element to an empty XML node in PowerShell? Other than that, you've avoided the biggest issue by showing us what you've tried in a succinct manner.Keith Hill

2 Answers

5
votes

That's because the Certificates property returns a string:

25> $xmlDoc.Role.Certificates.GetType().FullName
System.String

Because the element is a leaf element with no attributes, PowerShell simplifies the representation of the element to a string property that contains the element's content. You can get what you want by working around like this:

26> [xml]$xmlDoc = @'
>>>  <Role name="Role1">
>>>     <Instances count="2" />
>>>     <ConfigurationSettings>
>>>       <Setting name="Key1" value="123456" />
>>>       <Setting name="Key2" value="1234567890" />
>>>       <Setting name="Key3" value="true" />
>>>     </ConfigurationSettings>
>>>     <Certificates>
>>>     </Certificates>
>>>   </Role>
>>> '@
27> $certElem = $xmlDoc.CreateElement('Certificate')
28> $certElem.SetAttribute('name','certificate1')
29> $certElem.SetAttribute('thumbprint','12345678')
30> $xmlDoc.SelectSingleNode('/Role/Certificates').AppendChild($certElem)
31. $xmlDoc.Save($configFile)
1
votes

Thanks for that Keith, however i had some other issue as the cscfg file has a namespace.

The below code made it work without any issues. But this is when the xml is tied up to a namespace, specially in a CSCFG File in Azure Deployments

$xmlDoc = [System.Xml.XmlDocument](Get-Content $configFile);
$ns = New-Object System.Xml.XmlNamespaceManager($xmlDoc.NameTable)
$ns.AddNamespace("ns", $xmlDoc.DocumentElement.NamespaceURI)

$node = $xmlDoc.SelectSingleNode("//ns:Certificates", $ns)
$newNode = $xmlDoc.CreateElement("Certificate");
$newNode.SetAttribute('name',"certificate1")
$newNode.SetAttribute('value',"12345678")
$node.AppendChild($newNode)
$xmlDoc.save($configFile)

Thanks!!