Frage

I am creating a new object in PowerShell, using a hash table to set property values. I want to then export the object into XML format using the ConvertTo-XML method.

$hash = @{            
    Processor = 'Intel'                
    Disk = '500GB'
    Server = 'ABC'
    Serial = '01234'
}                           

$specs = New-Object PSObject -Property $hash
Write-Output ($specs | ConvertTo-XML -notypeinformation).Save("C:\scripts\export.xml")

The XML output is as follows:

<Objects>
  <Object>
    <Property Name="Serial">a1b2c3</Property>
    <Property Name="Server">ABC</Property>
    <Property Name="Processor">Intel</Property>
    <Property Name="Disk">500GB</Property>
  </Object>
</Objects>

What I want, is for the XML tags to be formatted in the following way:

<Objects>
  <Object>
    <Serial>a1b2c3</Serial>
    <Server>ABC</Server>
    <Processor>Intel</Processor>
    <Disk>500GB</Disk>
  </Object>
</Objects>

And then, if there is a good solution for that, is there also a way to make the Object(s) tags custom as well?

Thank you.

War es hilfreich?

Lösung

I don't think you can get there with ConvertTo-Xml. However, you can use here strings to do this. It is kind of low tech but still pretty cool:

$hash = @{            
    Processor = 'Intel'                
    Disk = '500GB'
    Server = 'ABC'
    Serial = '01234'
}                           

@"
<Objects>
  <Object>$(foreach ($kvpair in $hash.GetEnumerator()) {
    "`n    <$($kvpair.Key)>$($kvpair.Value)</$($kvpair.Key)>"
})
  </Object>
</Objects>
"@ > C:\scripts\export.xml

You could use the XML DOM to create this document but that would be more work and for such a simple document I think the here string approach works pretty well. It is also good for any sort of text templating.

Andere Tipps

Here's a one-liner:

$specs |% {'<Objects>'} {$_.psobject.properties |% {'  <Object>'} {"    <$($_.name)>$($_.value)</$($_.name)>"} {'  </Object>'} } {'</Objects>'}

Mjolinor's one liner is very useful for outputting from Powershell custom object tables in the XML format described above. However there is an error in it - the closing "/" xml tag is the wrong way round. This means that the XML code is invalid and give a '"XML Parsing Error: not well-formed"' error. Took me a while to figure out what was wrong, here is the corrected code so others do not have to figure it out again:

    $SelectedResults |% {'<Objects>'} {$_.psobject.properties |% {'  <Object>'} {"    <$($_.name)>$($_.value)</$($_.name)>"} {'  </Object>'} } {'</Objects>'}

Where $SelectedResults is the output of the PS Custom object.

You can test XML output and if it is valid here - https://www.w3schools.com/xml/xml_validator.asp

The selected answer worked for me but I had to change this line

"`n    <$($kvpair.Key)>$($kvpair.Value)</$($kvpair.Key)>"

to

"`n    <$($kvpair.Keys)>$($kvpair.Values)</$($kvpair.Keys)>"

Keys and Values instead of Key and Value

Also, if you want the spaces to be visible in notepad, use

`r`n

(I don't have enough reputation to comment on the answer)

If you're anything like me and can't understand the one-line answer, here it is expanded out:

$specs | ForEach-Object `
    -begin {'<Objects>'} `
    -process {$_.psobject.properties | ForEach-Object `
        -begin {'  <Object>'} `
        -process {"    <$($_.name)>$($_.value)</$($_.name)>"} `
        -end {'  </Object>'} } `
    -end {'</Objects>'} | out-file "C:\scripts\export.xml"
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top