Share via


PowerShell Function + Hash Table with multiple columns+ Return 2 values to main block from function

Question

Wednesday, June 13, 2018 7:49 PM

Hi everyone

I have the following code which I developed:

function Create_List_with_IP_Address {
    param (
    [Parameter(Mandatory=$False)][string]$ScriptPath = "C:\Users\username\Desktop\Scripts\Windows", # Path where the file with list of workstations exist
    [Parameter(Mandatory=$False)][string]$workstations_fqdn_list = "workstations_list_test_script.txt" # Full Path include file name that store the list of Workstations
    )
    Write-Host $ScriptPath
    Write-Host $workstations_fqdn_list
    $ErrorActionPreference = "silentlycontinue"
    
    $hash_no_working.Clear()
    $hash_no_working = @{}
    $hash_no_working.fqdn = @()
    $hash_no_working.ipaddress = @()
    $hash_no_working.ping = @()

    # $hash_no_working = @{"fqdn"="$null"; "ipaddress"="$null"; "ping"="$null"}
    
    <#
    $hash_no_working.fqdn = @()
    $hash_no_working.ipaddress = @()
    $hash_no_working.ping = @()
    #>
    
    Read-Host "Press Enter to Continue - Finished to Define the Hash Table: hash_no_working"
    Write-Host "hash_no_working (Keys): " -NoNewline
    $hash_no_working.Keys
    Read-Host "Press Enter to Continue"
    Write-Host "hash_no_working: " -NoNewline
    $hash_no_working
    $hash_no_working.fqdn
    $hash_no_working.ipaddress
    $hash_no_working.ping
    $hash_no_working
    Read-Host "Press Enter to Continue"

    $hash_yes_working.Clear()
    $hash_yes_working = @{}
    $hash_yes_working.fqdn = @()
    $hash_yes_working.ipaddress = @()
    $hash_yes_working.ping = @()

    # $hash_yes_working = @{"fqdn"="$null"; "ipaddress"="$null"; "ping"="$null"}
    
    <#
    $hash_yes_working.fqdn = @()
   $hash_yes_working.ipaddress = @()
    $hash_yes_working.ping = @()
    #>

    Read-Host "Press Enter to Continue - Finished to Define the Hash Table: hash_yes_working"
    Write-Host "hash_yes_working (Keys): " -NoNewline
    $hash_yes_working.Keys
    Read-Host "Press Enter to Continue"
    Write-Host "hash_yes_working: " -NoNewline
    $hash_yes_working
    
    # $i = 0
    #Debug Only # for ($i = 0; $i -le 50; $i++) {
    $workstations = Get-Content -Path "$ScriptPath\$workstations_fqdn_list"
    Write-Host $workstations
    foreach ($workstation in $workstations) {
        # Debug Only # $workstation = $workstations_fqdn_list[$i]
        $fqdn_resolve = [System.Net.DNS]::Resolve($workstation).HostName
        Write-Host "fqdn_resolve: " -NoNewline
        Write-Host $fqdn_resolve
        $ipaddress_resolve = [System.Net.DNS]::Resolve($workstation).AddressList.IPAddressToString
        Write-Host "ipaddress_resolve: " -NoNewline
        Write-Host $ipaddress_resolve
        If ($(Test-Connection -ComputerName $ipaddress_resolve -Count 3 -Quiet)) {
            $hash_yes_working.fqdn += @($fqdn_resolve)
            $hash_yes_working.ipaddress += @($ipaddress_resolve)
            $hash_yes_working.ping += @("yes")
        }
        Else {
            $hash_no_working.fqdn += @($fqdn_resolve)
            $hash_no_working.ipaddress += @($ipaddress_resolve)
            $hash_no_working.ping += @("no")
        }   
    }
    Write-Host "hash_yes_working"
    $hash_yes_working.Keys
    Write-Host $($hash_yes_working | Out-String)
       
    Write-Host "hash_no_working"
    $hash_no_working.Keys
    Write-Host $($hash_no_working | Out-String)
    Read-Host "Press Enter Before Exiting the Function and Returning a Value"
    $hash_yes_working.GetType().FullName
    $hash_no_working.GetType().FullName
    return $hash_yes_working,$hash_no_working
}

in this code I would like to built a Hash table which has multiple columns/rows.

the columns/rows are:

fqdn
ipaddress
ping

inside each hash table , each columns/rows can have multiple values (for that reason I am creating array for each columns/rows.

also , when the function end , I am trying to return 2 values.

in reality it doesn't work. 1 variable that suppose to catch 1 return value is empty and the 2nd variable that supposed to catch the 2nd return value has all information inside it.

what is wrong in my code ?

All replies (5)

Wednesday, June 13, 2018 8:09 PM

A hash table is only an array of name/value pairs.  It cannot have "columns" beyond "Name" and "Value".  It can have as many unique named entries as you like.

What you are trying to do is unclear. What is the desired outcome?

\(ツ)_/


Wednesday, June 13, 2018 8:13 PM

I recommend using custom objects for your code.

[pscustomobject]@{
**    name1 = somevalue**
**    name2 = somevalue**
**    name3= somevalue**
}

Output these to an array. You can have as many columns as you need.

Search for blog posts describing how to create and use custom objects.

\(ツ)_/


Thursday, June 14, 2018 4:53 PM

Perhaps I was not explaining my self good enough. so I will provide more information.

Generally speaking , The function is intended to get as an input a text file that contain hostnames or fqdn list of computers and to test each one of the computers and generate 2 lists , one with IP address and fqdn of computers that respond to PING test and the 2nd list will include all the computers that were not responding to PING Test.

The list which I intended to create will include the following values:

fqdn = the fqdn address of the computer

ipaddress = the ip address of the computer

ping = value can be yes or no

I am willing to create 2 seperated lists , while the 1st list ping value will be "yes" and the 2nd list ping value will be "no"

"yes" means that the computer that has been tested was responded successfully to PING test

"no" means that the computer that has been tested was not responded successfully to PING test

Initially when I opened this thread post on this forum I used the term column.
I understand that Hash table include only 2 columns , one intended to act as "Key" and the 2nd intended to act as "value" for the key.

because , it's a good idead to practice different ways of programming skills.

then I would like to create the value as Array of String.

per say , the fqdn will be the key and the value will be an Array of String.

and the same for ipaddress and also for ping.

after that before the powershell executor is exiting the from the function block then I am willing that the function will return 2 values.
each of the return values will be hash table.

thanks in advanced for the assistance.


Thursday, June 14, 2018 6:01 PM

That is absolutely silly.  Who told you to do this?.

If you return a list of all computers with those three fields you, in fact, have two lists.

It takes only about 12 lines of code to do that.

$results = $computers |
    ForEach-Object{
        $IPAddresses = Try{
            [System.Net.Dns]::GetHostAddresses($_)
        }
        Catch{}
        [pscustomobject]@{
            Computer = $_
            IpAddress = $IPAddresses
            PingStatus = Test-Connection $_ -Quiet
        }
    }

# good computers list
$results | where{$_.PingStatus}

# bad computers
$results | where{-not $_.PingStatus}

\(ツ)_/


Friday, June 15, 2018 7:56 PM

Hi jrv

I know that if I have those 3 fields those are more than enough and in actually it's like having 2 lists.

but , I was coming into this forum not to get an idea how to write the script and in which logic.

I came into to this forum to learn.

I know that my script is not the ideal script. but this was jumping into my head in the 1st place.

BUT , this is how you improve your self.

again , my question is still open.

1) Perhaps I implement this script with 2 hash tables. is it possible to have 1 key field and 1 value field and the value field will be actual an Array ? if yes , please take a look on my code and let me know what's wrong in the implementation in case I want to have 2 hash tables , and each one will have 3 keys and 3 values and in each value the content will be an Array of String.

2) How to implement a return of a function that should return 2 values which both of them are Hash Tables that include inside each of them an Array of String.

thx again JRV for the assistance.