【问题标题】:Foreach loop vs if/elseif in nested hashtable using Powershell使用 Powershell 的嵌套哈希表中的 Foreach 循环与 if/elseif
【发布时间】:2018-12-11 19:32:44
【问题描述】:

我的目标是创建一个 PowerShell 脚本,用于监控主机硬件运行状况并在组件状态不是“绿色”时发出警报(通过退出代码)。默认情况下,从软件 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 语句,其中 if host.value 为“GREEN”,然后退出 0(表示它已启动)并输出一条消息。

否则,执行 foreach 循环来搜索并确定哪个组件不是“绿色”。这就是我坚持逻辑的地方。

我遇到的第一个问题是不知道 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;
    }
}

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

【问题讨论】:

    标签: powershell if-statement foreach hashtable solarwinds-orion


    【解决方案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 语句来遍历每个驱动器。

    【讨论】:

      猜你喜欢
      • 2014-11-28
      • 2021-06-22
      • 1970-01-01
      • 2023-04-02
      • 2021-07-08
      • 1970-01-01
      • 2021-11-25
      • 2017-12-14
      • 2023-03-21
      相关资源
      最近更新 更多