Powershell newbie here. I need to write a script that will read the basename of multiple XML files and then use that value as data to populate a new element which will also be created by the running of the script. So each XML will be updated with one new element which contains the filename of that XML.
I don't seem to be grasping the proper syntax for looping through the files. The best results I've managed will write the element tags and the data within, but it writes everything to every file. So if I have three XML files in the target directory, each file will be updated with three instances of the new element (one element containing its own filename, and the other two containing the filenames of the other two XML files).
I have tried a few different approaches; treating the elements as strings seems to be the easiest for a beginner like myself, but I've tried inserting the fields as XML elements as well (to no avail). Here is the relevant snippet of the XML, before being updated (each of these elements is a child of the root element of the XML, with no descendants of their own):
<CustomerNumber>1234</CustomerNumber>
<OrderDate>2018-04-19</OrderDate>
After processing, the updated file will be as follows:
<CustomerNumber>1234</CustomerNumber>
<OrderNumber>A5678</OrderNumber>
<OrderDate>2018-04-19</OrderDate>
So I'll be inserting the basename of the file ("A5678" from "A5678.xml") as the order number. I've run through many iterations of the code, but here is what I most recently attempted:
$AllFiles = Get-ChildItem "C:\Powershell\Projects\Orders\*.xml";
$FileNames = New-Object System.Collections.ArrayList;
$OrderNum = @'
<OrderNumber>$Name</OrderNumber>`r`n<OrderDate>
'@
ForEach($File in $AllFiles)
{
$FileNames.Add($File.Name.SubString(0,5));
}
$UniqueNames = $FileNames | get-unique;
ForEach($Name in $UniqueNames)
{
Get-ChildItem $AllFiles | ForEach {
(Get-Content $_ | ForEach {$_ -replace '<OrderDate>', $ExecutionContext.InvokeCommand.ExpandString($OrderNum)}) | Set-Content $_
}}
As you can see, this attempt treats the elements as strings. I am using the opening tag of the immediately-following element as a point of reference for the replacement, because that is a field that will always be present. The preceding element, although required, may not always immediately precede. (An optional element, CustomerName, will sometimes precede the OrderDate.)
I'm not too sure about the use of "$ExecutionContext.InvokeCommand.ExpandString" - I just learned it from another user here, and though it worked in my last script, I don't know that this is also the proper application (I thought I had grasped the underlying concept, but that appears to not be the case). I readily confess to only the most superficial understanding of these concepts, and though I'm now constantly researching and learning about Powershell, I've only just scratched the surface.
Thanks for any assistance you can provide.