簡體   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