使用Powershell的嵌套哈希表中的Foreach循环与if/elseif

使用Powershell的嵌套哈希表中的Foreach循环与if/elseif,powershell,if-statement,foreach,hashtable,solarwinds-orion,Powershell,If Statement,Foreach,Hashtable,Solarwinds Orion,我的目标是创建一个PowerShell脚本,用于监视主机硬件运行状况,并在组件状态不是“绿色”时发出警报(通过退出代码)。默认情况下,以下信息作为哈希表从软件API中提取 为了便于阅读,这是JSON格式的信息,我使用convertto-JSONcmdlet将其转换为: "host": { "serial_number": "55555", "status": "GREEN", "name": "hostname

我的目标是创建一个PowerShell脚本,用于监视主机硬件运行状况,并在组件状态不是“绿色”时发出警报(通过退出代码)。默认情况下,以下信息作为哈希表从软件API中提取

为了便于阅读,这是JSON格式的信息,我使用convertto-JSONcmdlet将其转换为:

"host":  {
             "serial_number":  "55555",
             "status":  "GREEN",
             "name":  "hostname",
             "raid_card":  {
                               "serial_number":  "55555",
                               "status":  "GREEN",
                               "product_name":  "PRODUCT",
                           },
             "battery":  {
                             "percent_charged":  100,
                             "health":  "HEALTHY",
                             "status":  "GREEN"
                         },
             "accelerator":  {
                                      "temperature":  36,
                                      "status":  "GREEN"
                                  },
             "logical_drives":  [
                                    "@{serial_number=55555555555; health=HEALTHY}",
                                    "@{serial_number=55555555556; health=HEALTHY}"
                                ]
         }
}
如果任何组件(电池、raid_卡、加速器或逻辑_驱动器)不是绿色,则top host.status值将更改为“红色”

我设想的逻辑是执行一个初始的if语句,其中if host.value为“绿色”,然后退出0(表示它已启动),并只输出一条消息

否则,做一个foreach循环来搜索并确定哪个组件不是“绿色”的。这就是我被逻辑卡住的地方

我遇到的第一个问题是不知道foreach循环是否最适合这个问题。如果是这样的话,您如何构造foreach循环,因为其中一个组件逻辑驱动器内部有一个嵌套的哈希表

我遇到的第二个问题是,如果状态不是“绿色”,如何检索组件名称

我没走多远,但这是我最初采用的结构:

if (host.value -eq "GREEN"){
Write-Host "Message: host hardware is healthy"
Exit 0;
}

else{
    foreach ($components in $response.host){
       if ($_.status -ne "GREEN){
       Write-Host "Message: host.??? is not healthy"
       Exit 1;
       }
}
另一种结构是只执行if/elseif语句,而不是foreach循环。问题是它不是很优雅,而且它的重复性表明有更好的方法

if (host.value -eq "GREEN"){
Write-Host "Message: host hardware is healthy"
Exit 0;
}

else{
    if (host.raid_card.status -ne "GREEN"){
    Write-Host "Message: host.raid_card.product_name is not healthy"
    Exit 1;
    }

    elseif (host.battery.status -ne "GREEN"){
    Write-Host "Message: host battery is host.battery.status"
    Exit 1;
    }

    elseif (host.accelerator.status -ne "GREEN"{
    Write-Host "Message: accelerator temperature is host.accelerator.temperature"
    Exit 1;
    }
}

任何关于如何更好地构建此结构的建议都将不胜感激

我建议将要迭代的组件放在结构中更深一步,并确保每个组件都有类似的“状态”属性要检查(在json示例中不是这样):

当您准备好后,可以使用如下代码检查每个组件的状态:

# Set up an return variable (exit code)
[int]$exitCode = 0

# $machine is the variable name i used to import the json above
if ($machine.host.status -eq "GREEN") {
    Write-Host "Message: Machine $($machine.host.name) - hardware is healthy"
}
else {
    foreach ($component in $machine.host.components.PSObject.Properties) { 
        if ($component.Value.status -ne "GREEN") {
            Write-Host "Message: Machine $($machine.host.name) - $($component.Name) is not healthy"
            $exitCode = 1
        }
    }
}

Exit $exitCode
当然,您有不同的项目在那里,现在我可以看到,逻辑驱动器阵列可能是一个问题。如果您想让脚本告诉您哪个逻辑驱动器导致状态为“非绿色”,您需要在foreach循环中提供If语句以迭代每个驱动器

# Set up an return variable (exit code)
[int]$exitCode = 0

# $machine is the variable name i used to import the json above
if ($machine.host.status -eq "GREEN") {
    Write-Host "Message: Machine $($machine.host.name) - hardware is healthy"
}
else {
    foreach ($component in $machine.host.components.PSObject.Properties) { 
        if ($component.Value.status -ne "GREEN") {
            Write-Host "Message: Machine $($machine.host.name) - $($component.Name) is not healthy"
            $exitCode = 1
        }
    }
}

Exit $exitCode