2

Is it possible to insert a variable from PowerShell into an XML format? ex. I have declared $SIDadm = sidadm as a global variable and i want it to be inserted on xml code below

[xml]$REST2 = 
'<config xmlns="http://www.sap.com/lmsl/slp">
<Parameter>
<id>JeeAdminPassword</id>
<value>mkSVQW1zMi070N</value>
</Parameter>
<Parameter>
<id>SidAdmUserPassword</id>
<value>cB8y@OSLHu@DcNPa</value>
</Parameter>
<Parameter>
<id>NoCredentialsMode</id>
<value>false</value>
</Parameter>
<Parameter>
<id>SidAdmUserName</id>
<value>$SIDadm</value>
</Parameter>
<Parameter>
<id>EHPStackFile</id>
<value>F:/SAPSoftware/J3M_MII15.1_SP3_Patch_1/Stack_generic.xml</value>
</Parameter>
<Parameter>
<id>SapSystemInstance[]</id>
<value>2</value>
</Parameter>
<Parameter>
<id>SapSystemInstance[0].SidAdmUserPassword</id>
<value>cB8y@OSLHu@DcNPa</value>
</Parameter>
<Parameter>
<id>SapSystemInstance[0].InstanceNumber</id>
<value>0</value>
</Parameter>
<Parameter>
<id>SapSystemInstance[0].SidAdmUserName</id>
<value>GLOBEDDC\j3ladm</value>
</Parameter>
<Parameter>
<id>SapSystemInstance[0].HostName</id>
<value>j3lsap</value>
</Parameter>
<Parameter>
<id>SapSystemInstance[1].SidAdmUserPassword</id>
<value>cB8y@OSLHu@DcNPa</value>
</Parameter>
<Parameter>
<id>SapSystemInstance[1].HostName</id>
<value>j3lsap</value>
</Parameter>
<Parameter>
<id>SapSystemInstance[1].InstanceNumber</id>
<value>2</value>
</Parameter>
<Parameter>
<id>SapSystemInstance[1].SidAdmUserName</id>
<value>GLOBEDDC\j3ladm</value>
</Parameter>
<Parameter>
<id>InstanceName</id>
<value>JC00</value>
</Parameter>
<Parameter>
<id>SystemId</id>
<value>J3L</value>
</Parameter>
<Parameter>
<id>JeeAdminUser</id>
<value>Administrator</value>
</Parameter>
</config'

return $REST2

Basically I want to insert $SIDadmwhich has a value of sidadm into the XML. like this under the (id)SidAdmUserName(/id) its (value) would be (value)sidadm(/value)

[xml]$REST2 = 
'<config xmlns="http://www.sap.com/lmsl/slp">
<Parameter>
<id>JeeAdminPassword</id>
<value>mkSVQW1zMi070N</value>
</Parameter>
<Parameter>
<id>SidAdmUserPassword</id>
<value>cB8y@OSLHu@DcNPa</value>
</Parameter>
<Parameter>
<id>NoCredentialsMode</id>
<value>false</value>
</Parameter>
<Parameter>
<id>SidAdmUserName</id>
<value>sidadm</value>
</Parameter>
<Parameter>
<id>EHPStackFile</id>
<value>F:/SAPSoftware/J3M_MII15.1_SP3_Patch_1/Stack_generic.xml</value>
</Parameter>
<Parameter>
<id>SapSystemInstance[]</id>
<value>2</value>
</Parameter>
<Parameter>
<id>SapSystemInstance[0].SidAdmUserPassword</id>
<value>cB8y@OSLHu@DcNPa</value>
</Parameter>
<Parameter>
<id>SapSystemInstance[0].InstanceNumber</id>
<value>0</value>
</Parameter>
<Parameter>
<id>SapSystemInstance[0].SidAdmUserName</id>
<value>GLOBEDDC\j3ladm</value>
</Parameter>
<Parameter>
<id>SapSystemInstance[0].HostName</id>
<value>j3lsap</value>
</Parameter>
<Parameter>
<id>SapSystemInstance[1].SidAdmUserPassword</id>
<value>cB8y@OSLHu@DcNPa</value>
</Parameter>
<Parameter>
<id>SapSystemInstance[1].HostName</id>
<value>j3lsap</value>
</Parameter>
<Parameter>
<id>SapSystemInstance[1].InstanceNumber</id>
<value>2</value>
</Parameter>
<Parameter>
<id>SapSystemInstance[1].SidAdmUserName</id>
<value>GLOBEDDC\j3ladm</value>
</Parameter>
<Parameter>
<id>InstanceName</id>
<value>JC00</value>
</Parameter>
<Parameter>
<id>SystemId</id>
<value>J3L</value>
</Parameter>
<Parameter>
<id>JeeAdminUser</id>
<value>Administrator</value>
</Parameter>
</config'

$nsm = New-Object Xml.XmlNamespaceManager($REST2.NameTable)
$nsm.AddNamespace('ns', $REST2.DocumentElement.NamespaceURI)

$xpath = '/ns:config/ns:parameter[ns:id/text()="SidAdmUserName"]/ns:value'

$REST2.SelectSingleNode($xpath, $nsm).'#text' = $SIDadm
$REST2.Save([Console]::Out)

return $REST2
Thereal jubster
  • 43
  • 1
  • 1
  • 6
  • It's not clear to me what you're asking here. Do you have XML with variables in it and want to expand the variables to their value? Insert the variables into the XML (template)? Insert their values into the XML (template)? Just a specific variable or all of them? Something else entirely? – Ansgar Wiechers Jan 05 '17 at 12:16
  • i want to use the $SIDadm variable from powershell inside the xml format sorry for being unclear first time posting here @AnsgarWiechers – Thereal jubster Jan 05 '17 at 12:25

1 Answers1

4

To expand variables in an XML string you can use the automatic variable $ExecutionContext:

$str = @'
<config xmlns="http://www.sap.com/lmsl/slp">
  <parameter>
    <id>SidAdmUserName</id>
    <value>$SIDadm</value>
  </parameter>
</config>
'@

$ExecutionContext.InvokeCommand.ExpandString($str)

Beware that this will expand all expandable expressions in the string (e.g. something like $(Get-ChildItem) would be expanded as well).

If you want to expand just a variable in a single element you could try with a simple string replacement:

$str = @'
<config xmlns="http://www.sap.com/lmsl/slp">
  <parameter>
    <id>SidAdmUserName</id>
    <value>$SIDadm</value>
  </parameter>
</config>
'@

$str.Replace('$SIDadm', $SIDadm)

However, that may also yield undesired results, e.g. if there are several variables starting with the same partial name. Something like

<config xmlns="http://www.sap.com/lmsl/slp">
  <parameter>
    <id>SidAdmUserName</id>
    <value>$SIDadm</value>
  </parameter>
  <parameter>
    <id>SidAdmPassword</id>
    <value>$SIDadmPassword</value>
  </parameter>
</config>

would become

<config xmlns="http://www.sap.com/lmsl/slp">
  <parameter>
    <id>SidAdmUserName</id>
    <value>j3ladm</value>
  </parameter>
  <parameter>
    <id>SidAdmPassword</id>
    <value>j3ladmPassword</value>
  </parameter>
</config>

In situations like that it's better to parse the XML, select the particular node, and replace the content of just that node:

[xml]$xml = @'
<config xmlns="http://www.sap.com/lmsl/slp">
  <parameter>
    <id>SidAdmUserName</id>
    <value>$SIDadm</value>
  </parameter>
  <parameter>
    <id>SidAdmPassword</id>
    <value>$SIDadmPassword</value>
  </parameter>
</config>
'@

$nsm = New-Object Xml.XmlNamespaceManager($xml.NameTable)
$nsm.AddNamespace('ns', $xml.DocumentElement.NamespaceURI)

$xpath = '/ns:config/ns:parameter[ns:id/text()="SidAdmUserName"]/ns:value'

$xml.SelectSingleNode($xpath, $nsm).'#text' = $SIDadm
$xml.Save([Console]::Out)

Note that you MUST use a namespace manager here, because your XML uses namespaces.

Community
  • 1
  • 1
Ansgar Wiechers
  • 193,178
  • 25
  • 254
  • 328
  • @Therealjubster Please do not accept an answer before you have verified that the proposed solution actually does what you expect it to do. – Ansgar Wiechers Jan 05 '17 at 13:07
  • hello @AnsgarWiechers im getting an error it says invocation failed because [System.Xml.XmlDocument] doesn't contain a method named 'Replace'. when insert the .replace method – Thereal jubster Jan 06 '17 at 09:58
  • @Therealjubster That's because you mixed my examples. Don't do that. The first two examples use XML **strings**, whereas the last example uses an `XmlDocument` **object**. The latter does not have a `Replace()` method. – Ansgar Wiechers Jan 06 '17 at 10:06
  • hmm so is there anyway for my variable $SIDadm to be inserted into a XML template? – Thereal jubster Jan 06 '17 at 10:39
  • @Therealjubster I showed you 3 different ways in my answer, didn't I? Why don't you update your question with a sample of what your XML template looks like now, and what you want it to look like after the intended modification? – Ansgar Wiechers Jan 06 '17 at 10:48
  • @Therealjubster Before ***and*** after. Show how the *result* is supposed to look like as well. – Ansgar Wiechers Jan 06 '17 at 11:07
  • ok here its updated and thank you again for helping me with my problem of mine really appreciate it – Thereal jubster Jan 06 '17 at 11:18
  • @Therealjubster See updated answer. Also, note that there's a closing angular bracket missing at the end of the XML strings in your question. – Ansgar Wiechers Jan 06 '17 at 11:41
  • Umm question sorry if this would sound stupid haha but under the line code $xml.SelectNodes($xpath, $nsm).'#text' = $SIDadm. Is '#Text' where i am suppose to put the word to be replaced? – Thereal jubster Jan 06 '17 at 12:45
  • @Therealjubster How about you actually ***try*** it and see what it does, instead of waiting for me to spoon-feed you a solution? – Ansgar Wiechers Jan 06 '17 at 13:06
  • Sorry to bother but when i ran it i get the error Property '$SIDadm' cannot be found on this object; make sure it exists and is settable. i inserted $SIDadm onto #Text since from my understanding thats the value i want to change. Its my first time in powershell using xml im really sorry for all the questions. – Thereal jubster Jan 06 '17 at 13:31
  • Well, yes, you need to actually define `$SIDadm = 'j3ladm'` before you can use the variable. Did you expect it to suddenly appear out of thin air? – Ansgar Wiechers Jan 06 '17 at 13:34
  • i decalred my $SIDadm as a global variable and is also declared before running this code, from my understanding the line ( correct me if wrong but ) $xml.SelectNodes($xpath, $nsm).'#text' im am selecting the node SidAdmUserName$SIDadm and im replacing the value to the value i want right? – Thereal jubster Jan 06 '17 at 13:41
  • Ah, I see. I had 2 mistakes in the code handling the XML. The XPath expression needed to use the namespace identifier, and `SelectNodes()` returns a collection, which doesn't have a property `#text`. See updated answer. – Ansgar Wiechers Jan 06 '17 at 13:48
  • $REST2.SelectSingleNode($xpath, $nsm).'$SIDadm' = $SIDadm. I am now using this and it still giving me the same error – Thereal jubster Jan 06 '17 at 13:58
  • The property name is still `.'#text'`, not `.'$SIDadm'`. – Ansgar Wiechers Jan 06 '17 at 14:06
  • hello again after much researching im still getting the same error Property '#text' cannot be found on this object; make sure it exists and is settable. I set the '$SIDadm' to '#text' and im still getting the same error – Thereal jubster Jan 09 '17 at 16:28
  • i have updated the code from above that is my current code right now – Thereal jubster Jan 09 '17 at 16:48
  • XPath is case sensitive. The `` tags in your XML are written with a capital `P`. – Ansgar Wiechers Jan 09 '17 at 16:53
  • OMG THANK YOU @AnsgarWiechers ITS WORKING sorry for the questions but i really learned alot THANK YOU SO MUCH!!! – Thereal jubster Jan 09 '17 at 16:59