Mohit Toshniwal Mohit Toshniwal - 3 months ago 35
PowerShell Question

Need Help To Get XML Values In Array Using POWERSHELL

I have an XML Output from a FIRMWARE CHECK Script on a HPE Server.
I want to create an array to define

FIRMWARE_NAME VALUE
=
FIRMWARE_VERSION VALUE
for each index.

As you can see that Path is not consistent and there can be more or less index from server to server, hence creating a loop fails, probably because I am not good with PowerShell too and hence seeking some help.

A demo script is below:

$xml = [xml]@"
<HEAD>
<RIBCL VERSION="2.23">
<RESPONSE
STATUS="0x0000"
MESSAGE='No error'
/>
<GET_EMBEDDED_HEALTH_DATA>
<FIRMWARE_INFORMATION>
<INDEX_1>
<FIRMWARE_NAME VALUE = "iLO"/>
<FIRMWARE_VERSION VALUE = "2.40 Dec 02 2015"/>
</INDEX_1>
<INDEX_2>
<FIRMWARE_NAME VALUE = "System ROM"/>
<FIRMWARE_VERSION VALUE = "I31 06/01/2015"/>
</INDEX_2>
<INDEX_3>
<FIRMWARE_NAME VALUE = "Redundant System ROM"/>
<FIRMWARE_VERSION VALUE = "I31 04/01/2015"/>
</INDEX_3>
<INDEX_4>
<FIRMWARE_NAME VALUE = "Intelligent Provisioning"/>
<FIRMWARE_VERSION VALUE = "1.62.31"/>
</INDEX_4>
<INDEX_5>
<FIRMWARE_NAME VALUE = "Intelligent Platform Abstraction Data"/>
<FIRMWARE_VERSION VALUE = "1.55"/>
</INDEX_5>
<INDEX_6>
<FIRMWARE_NAME VALUE = "System ROM Bootblock"/>
<FIRMWARE_VERSION VALUE = "03/05/2013"/>
</INDEX_6>
<INDEX_7>
<FIRMWARE_NAME VALUE = "Power Management Controller Firmware"/>
<FIRMWARE_VERSION VALUE = "3.3"/>
<FIRMWARE_FAMILY VALUE = "0Ch"/>
</INDEX_7>
<INDEX_8>
<FIRMWARE_NAME VALUE = "Power Management Controller Firmware Bootloader"/>
<FIRMWARE_VERSION VALUE = "2.7"/>
</INDEX_8>
<INDEX_9>
<FIRMWARE_NAME VALUE = "System Programmable Logic Device"/>
<FIRMWARE_VERSION VALUE = "Version 0x13"/>
</INDEX_9>
<INDEX_10>
<FIRMWARE_NAME VALUE = "Server Platform Services (SPS) Firmware"/>
<FIRMWARE_VERSION VALUE = "2.1.7.E7.4"/>
</INDEX_10>
<INDEX_11>
<FIRMWARE_NAME VALUE = "Smart Array P220i Controller"/>
<FIRMWARE_VERSION VALUE = "6.68"/>
</INDEX_11>
<INDEX_12>
<FIRMWARE_NAME VALUE = "HP FlexFabric 10Gb 2-port 554FLB Adapter"/>
<FIRMWARE_VERSION VALUE = "10.5.155.0"/>
</INDEX_12>
</FIRMWARE_INFORMATION>
</GET_EMBEDDED_HEALTH_DATA>
</RIBCL>
</HEAD>
"@


EXPECTED OUTPUT: in the array


iLO= 2.40 Dec 02 2015

System ROM= I31 06/01/2015

Redundant System ROM= I31 04/01/2015

Intelligent Provisioning= 1.62.31

Intelligent Platform Abstraction Data= 1.55

System ROM Bootblock= 41338

Power Management Controller Firmware= 3.3

Power Management Controller Firmware Bootloader= 2.7

System Programmable Logic Device= Version 0x13

Server Platform Services (SPS) Firmware= 2.1.7.E7.4

Smart Array P220i Controller= 6.68

HP FlexFabric 10Gb 2-port 554FLB Adapter= 10.5.155.0

Answer

I tried to just add this as a comment to Martin Brandl's answer but I couldn't get the formatting of the code to look right.

To expand on Martin Brandl's answer, if you wanted the results in object form, you could do something like this:

$FirmwareVersions = $xml.DocumentElement.RIBCL.GET_EMBEDDED_HEALTH_DATA.FIRMWARE_INFORMATION.ChildNodes | ForEach-Object {
    [pscustomobject]@{
        Name = $_.FIRMWARE_NAME.Value;
        Version = $_.FIRMWARE_VERSION.Value
    }
}

Based on your comments:

If you want one object with the property names to be the different devices and the value to be the firmware levels (and then exported to CSV), here is how I would do that:

$FirmwareVersions = New-Object -TypeName PSObject
$xml.DocumentElement.RIBCL.GET_EMBEDDED_HEALTH_DATA.FIRMWARE_INFORMATION.ChildNodes | ForEach-Object {
    $FirmwareVersions | Add-Member -MemberType NoteProperty -Name $_.FIRMWARE_NAME.Value -Value $_.FIRMWARE_VERSION.Value
}
$FirmwareVersions | Export-Csv -NoTypeInformation -Path .\FirmwareVersions.csv

There may be a shorter syntax for doing that, but this was the way that came most natural to me. The code creates a new custom object and then cycles through the child nodes of the XML to add a new property to the custom object with the firmware name and the firmware value.

Comments