1

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.

Pradebban Raja
  • 443
  • 5
  • 20
  • Why was this question voted down?? If the reader does not know the answer, will it be voted down ?? – Pradebban Raja Apr 05 '15 at 21:45
  • 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 Apr 05 '15 at 22:20

2 Answers2

7

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)
Keith Hill
  • 194,368
  • 42
  • 353
  • 369
  • This is what exactly answers the original question. This should be the accepted answer... Thank you very much, @Keith, saved me hours. – toscanelli Dec 11 '19 at 15:58
1

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!!

Pradebban Raja
  • 443
  • 5
  • 20
  • The @Keith answer should be the accepted one, because it answers exactly what you asked, and because he gave you the clue of what other problems you were having... – toscanelli Dec 11 '19 at 16:01