繁体   English   中英

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

[英]Foreach loop vs if/elseif in nested hashtable using Powershell

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

出于可读性考虑,这是JSON格式的信息,我使用convertto-json cmdlet进行了转换:

"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_card,加速器或逻辑驱动器)不是绿色,则最上面的host.status值将更改为“ RED”。

我设想的逻辑是执行一个初始if语句,其中如果host.value为“ GREEN”,则退出0(表示启动)并仅输出一条消息。

否则,执行一个foreach循环以搜索和识别哪个组件不是“ GREEN”。 这就是我坚持逻辑的地方。

我遇到的第一个问题是不知道foreach循环是否最适合此问题。 如果是这样,由于组件之一(逻辑驱动器)内部具有嵌套的哈希表,因此如何构造foreach循环。

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

我没有走很远,但这是我最初要使用的结构:

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示例中不是这种情况),如下所示:

{
    "host": {
        "serial_number": "55555",
        "status": "GREEN",
        "name": "hostname",
        "components": {
            "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",
                "status": "GREEN"
            }
        }
    }
}

将其放置在适当的位置后,可以使用如下代码检查每个组件的状态:

# 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语句来遍历每个驱动器。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM