Search code examples
powershellfor-loophashtable

Looping through a hash table, finding a value less than a number, and adding that to a new hashtable


I have a server name as a key and its available space as its value like:

    $hash= @{}
#in the loop I get the server name and then I get the space as an integer and add it to the table like:
    $hash.add($server,$space)

after the loops are complete, I want to go through the list and add the servers with a space less than 80 to a different table using

    $badServers = foreach($entry in $serverSpace){
    if($entry.Keys -le 80){
    $badServers.add($entry) 
    }}

but my output ends up putting every server into $badServers. Its as if the Values arent actually whats listed. Not sure what Im doing wrong.


Solution

  • Assuming the values of your hashtable are of the type [int], for example:

    PS /> $hash
    
    Name                           Value
    ----                           -----
    SERVER0                        93   
    SERVER1                        87   
    SERVER2                        84   
    SERVER3                        92   
    SERVER4                        83   
    SERVER5                        58   
    SERVER6                        95   
    SERVER7                        62   
    SERVER8                        81   
    SERVER9                        84   
    SERVER10                       59   
    

    You could do something like this:

    $result = foreach($key in $hash.Keys)
    {
        if($hash[$key] -lt 80)
        {
            [pscustomobject]@{
                Server = $key
                Space = $hash[$key]
            }
        }
    }
    

    And looking at $result you would get something like this:

    PS /> $result
    
    Server   Space
    ------   -----
    SERVER5     58
    SERVER7     62
    SERVER10    59
    

    If values were stored as [string] but holding an actual integer you would need to change the condition a bit:

    if([int]$hash[$key] -lt 80){ ... }
    

    Edit Note:

    Actually, my bad here, PowerShell is smart enough to know how to compare a string holding a number with an integer. There is no need to cast [int].


    And, for example, if the hash was holding values like 123 Gb, i.e.:

    PS /> $hash
    
    Name                           Value
    ----                           -----
    SERVER0                        94 Gb
    SERVER1                        80 Gb
    SERVER2                        82 Gb
    SERVER3                        89 Gb
    ...
    ...
    

    You could do something like:

    if([regex]::Match($hash[$key],'\d+').Value -lt 80){ ... }
    

    Which would yield:

    PS /> $result
    
    Server   Space
    ------   -----
    SERVER5  52 Gb
    SERVER6  53 Gb
    SERVER8  69 Gb
    SERVER9  72 Gb
    SERVER10 65 Gb