-1

I'm writing a powershell script to ping all the servers and check which are offline. but i have a bug. By name it works perfectly. But when i do test-connection with an IP it seems to work BUT i cant output the name of the IP in the hashlist. Could someone help me figure this out? Thanks!!

System.Collections.Hashtable.keys Is online/available, This is what it outputs. But i want it to say "Servername is online/available"

#Creating IP Array list
$ip_array = @{
Server = [ipaddress] "192.168.1.1"
sws = [ipaddress] "192.168.1.1"
}



Foreach ($ip in $ip_array)
{   
    if((Test-Connection -IPAddress $ip.values.ipaddresstostring -quiet -count 1 ) -eq $false)
    {
        
        write-output("$ip.keys  Is offline/unavailable, please troubleshoot connection, script is terminating")  | Red 
    }
    else
    {
        $ping = $true
        write-output("$ip.keys Is online/available") | Green
    }
}
S G
  • 29
  • 2
  • A simple way to iterate over hash table items is to use `GetEnumerator()` method. Then you have `foreach ($ip in $ip_array.GetEnumerator()) { $ip.Value.IPAddressToString }`. `$ip_array` is a hash table and not an array. Iteration doesn't work the same way. – AdminOfThings Oct 05 '21 at 13:49
  • @AdminOfThings Thanks for the prompt reply, i've made the adjustments and it does go through the hashtable now, i have two lines written everytime. But it still doesnt get the name of the key/value pair. I get this output System.Collections.DictionaryEntry.Name Is online/available System.Collections.DictionaryEntry.Name Is online/available Could you please let me know how to call the name? – S G Oct 05 '21 at 13:56
  • @SteveG That's because you embed the expression in a string literal. Do `"$($ip.Key) is the key"` instead of `"$ip.Key is the key"` – Mathias R. Jessen Oct 05 '21 at 13:59

2 Answers2

1

If you really intend to use a Hashtable for this, combining IP addresses with computernames, change to something like this:

# creating IP Hashtable
$ip_hash = @{
'192.168.1.1' = 'Server1'
'192.168.1.2' = 'Server2'
# etcetera
}
# loop through the hash, key-by-key
foreach ($ip in $ip_hash.Keys) {
    $ping = Test-Connection -ComputerName $ip -Quiet -Count 1 -ErrorAction SilentlyContinue
    if(!$ping) {
        Write-Host "Server $($ip_hash[$ip]) is offline/unavailable, please troubleshoot connection, script is terminating" -ForegroundColor Red
    }
    else {
        Write-Host "Server $($ip_hash[$ip]) is online/available" -ForegroundColor Green
    }
}

Output would look like:

enter image description here

The Keys in the hash must all have unique values

Theo
  • 57,719
  • 8
  • 24
  • 41
1

PowerShell's default pipeline semantics (any collection that can be enumerated and unraveled will be) makes dictionaries a pain to work with - piping them anywhere would result in a list of disjoint key-value-pairs, dictionary itself lost.

For this reason, PowerShell refuses to automatically enumerate dictionaries, and you must manually obtain an enumerator in order to loop over the entries in it:

foreach($entry in $ip_hash.GetEnumerator()){
  # reference `$entry.Key` or `$entry.Name` for the key (eg. Server)
  # reference `$entry.Value` for the value (eg. 192.168.1.1)
}
Mathias R. Jessen
  • 157,619
  • 12
  • 148
  • 206