0

Hi I have below script & when I am running this script its generating multiple XML based on one master XML now these xml have computer name info which should be updated in xml as below-

<ComputerName>Server1</ComputerName>

but showing as below which is not right format-

<ComputerName>Server1, server2, server3</ComputerName>

PS script as -

$template = Get-Content -Path 'C:\pscript\vj\MasterXML.xml' -Raw
$csv= Import-Csv 'C:\pscript\vj\CH21000546421_ProductID.csv'
Remove-Item 'C:\pscript\vj\dup.csv'
Remove-Item 'C:\pscript\vj\uniq.csv'


$csv |
Group-Object -Property ServerName |
Where-Object -FilterScript {
$_.Count -gt 1
} |
Select-Object -ExpandProperty Group| Export-Csv -Path 'C:\pscript\vj\dup.csv' -NoTypeInformation



Import-Csv -Path 'C:\pscript\vj\dup.csv' | Group-Object ServerName | ForEach-Object {
# replace the placeholders in the template. Sort the numeric values for neatness as we go.
$template -replace '#Title#', (([int[]]$_.Group.IGPID | Sort-Object) -join ', ') -replace
'#computername#', "<ComputerName>$($_.Name)</ComputerName>" |
Set-Content -Path "C:\pscript\vj\$($_.Name).xml" -Encoding UTF8
}

$csv |
Group-Object -Property ServerName |
Where-Object -FilterScript {
$_.Count -lt 2
} |
Select-Object -ExpandProperty Group| Export-Csv -Path 'C:\pscript\vj\uniq.csv' -NoTypeInformation
Import-Csv -Path 'C:\pscript\vj\uniq.csv' | Group-Object IGPID | ForEach-Object {
# replace the placeholders in the template. Sort the numeric values for neatness as we go.
$template -replace '#computername#',"<ComputerName>$(($_.Group.ServerName) -join ',')</ComputerName>" -replace
'#Title#', ($_.Name) |
Set-Content -Path "C:\pscript\vj\$($_.Name).xml" -Encoding UTF8

 }

I am sure below part is handling this comma separation, please help in how to update it so it will not break or effect code 1 in the script.

$template -replace '#computername#',"<ComputerName>$(($_.Group.ServerName) -join ',')</ComputerName>" -replace
3
  • Cleary the code was not written to do this. The issue is the ForEach-Object as is outputs a new file per every entry and is not written to appended strings to a single XML file. Commented Jun 6, 2021 at 2:36
  • Also, can you please provide your attempts to make the script work as you need? Otherwise it's a fully functional script. Commented Jun 6, 2021 at 2:39
  • Thanks Alex for your response ! yes script is working fine but the output is not correct or I would say not what I am expecting. I have no knowledge of scripting it was already in system but was not working the way it suppose to. I am playing with below bit - '#computername#',"<ComputerName>$(($_.Group.ServerName) -join ',')</ComputerName>" and this is the area where I am looking something to generate output as <ComputerName>Server1</ComputerName> not as <ComputerName>Server1, server2, server3</ComputerName>, I tried changing join by , to what I want but its not working. Commented Jun 6, 2021 at 7:34

1 Answer 1

1

If I understand correctly, you want to output an xml file for every server found in the 'CH21000546421_ProductID.csv' using a template, but having trouble with writing these out for the duplicate servernames.

If your template looks something like this:

<?xml version="1.0" encoding="utf-8"?>
<Servers>
  <Server title="#Title#">#computername#</Server>
</Servers>

and your input csv looks anything like this:

"IGPID","ServerName"
123,"Server1"
43,"Server2"
8,"Server3"
11,"Server1"
1,"Server1"
17,"Server3"

Then the below code should do what you want:

$template = Get-Content -Path 'C:\pscript\vj\MasterXML.xml' -Raw
$csv      = Import-Csv -Path 'C:\pscript\vj\CH21000546421_ProductID.csv' | Group-Object -Property ServerName

# get the duplicate servernames
$dupes = $csv | Where-Object { $_.Count -gt 1 }
# get the unique servernames
$uniq = $csv | Where-Object { $_.Count -lt 2 }
            
# save this as new csv files
$dupes | Select-Object -ExpandProperty Group | Export-Csv -Path 'C:\pscript\vj\dup.csv' -NoTypeInformation
$uniq  | Select-Object -ExpandProperty Group | Export-Csv -Path 'C:\pscript\vj\uniq.csv' -NoTypeInformation

# $dupes is already grouped by servername
$dupes | ForEach-Object {
    # remember you're iterating Groups with multiple items here!
    foreach ($item in $_.Group) {
        $template -replace '#Title#', $item.IGPID -replace '#computername#', "<ComputerName>$($item.ServerName)</ComputerName>" |
        # write an xml for each of the duplicates. By appending the IGPID to the name of the file
        Set-Content -Path "C:\pscript\vj\$($item.ServerName)_$($item.IGPID).xml" -Encoding UTF8
    }
}

# $uniq is already grouped by servername
$uniq | ForEach-Object {
    # or use -replace '#computername#', "<ComputerName>$($_.Group[0].ServerName)</ComputerName>"
    $template -replace '#Title#', $_.Group[0].IGPID -replace '#computername#', "<ComputerName>$($_.Name)</ComputerName>" |
    # write an xml for each of the unique servers.
    Set-Content -Path "C:\pscript\vj\$($_.Name).xml" -Encoding UTF8
}

Now you have several xml files, one for each server. The servers that were found as duplicate all have xml files named <servername>_<id>.xml.
The unique servers have files called <servername.xml>

Demo content of 'Server1_123.xml' (one of the duplicates)

<?xml version="1.0" encoding="utf-8"?>
<Servers>
  <Server title="123"><ComputerName>Server1</ComputerName></Server>
</Servers>

Demo content of the only unique server in the input file 'Server2.xml':

<?xml version="1.0" encoding="utf-8"?>
<Servers>
  <Server title="43"><ComputerName>Server2</ComputerName></Server>
</Servers>
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.