需要帮助使用POWERSHELL在数组中获取XML值

时间:2016-08-04 19:56:23

标签: arrays xml powershell xml-parsing

我有一个来自HPE服务器上的FIRMWARE CHECK脚本的XML输出。 我想创建一个数组来为每个索引定义FIRMWARE_NAME VALUE = FIRMWARE_VERSION VALUE

正如您所看到的那样,Path不一致,服务器之间可能存在更多或更少的索引,因此创建循环失败,可能是因为我对PowerShell也不好,因此寻求一些帮助。

演示脚本如下:

$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>
"@

预期输出:在数组中

  

iLO = 2.40 2015年12月2日

     

系统ROM = I31 06/01/2015

     

冗余系统ROM = I31 04/01/2015

     

Intelligent Provisioning = 1.62.31

     

智能平台抽象数据= 1.55

     

系统ROM Bootblock = 41338

     

电源管理控制器固件= 3.3

     

电源管理控制器固件Bootloader = 2.7

     

系统可编程逻辑器件=版本0x13

     

服务器平台服务(SPS)固件= 2.1.7.E7.4

     

Smart Array P220i控制器= 6.68

     

HP FlexFabric 10Gb双端口554FLB适配器= 10.5.155.0

2 个答案:

答案 0 :(得分:1)

您可以只检索FIRMWARE_INFORMATION节点的ChildNodes并迭代它们:

$xml.DocumentElement.RIBCL.GET_EMBEDDED_HEALTH_DATA.FIRMWARE_INFORMATION.ChildNodes | 
    ForEach-Object { "{0} = {1}" -f $_.FIRMWARE_NAME.Value, $_.FIRMWARE_VERSION.Value}

<强>输出:

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 = 03/05/2013
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

注意:这将创建一个字符串数组。如果要获取哈希表因为要检索键的值,则必须采用foreach对象内容...

答案 1 :(得分:1)

我试图将此添加为对Martin Brandl的回答的评论,但我无法将代码的格式设置为正确。

要扩展Martin Brandl的答案,如果你想以对象形式得到结果,你可以这样做:

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

根据您的评论

如果您希望一个具有属性名称的对象成为不同的设备,并将值作为固件级别(然后导出为CSV),请按以下步骤操作:

$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

这样做的语法可能会更短,但这对我来说是最自然的方式。代码创建一个新的自定义对象,然后循环遍历XML的子节点,以使用固件名称和固件值向自定义对象添加新属性。