Seeking advice/help with data retrieval from an array of hash tables

I’m trying to understand storing and retrieving data using an array of hashtables. I am able to get the data I’m interested in and store it into a hash table. Then add that hash table to an array. The variable.count shows the right amount of hash table objects. I’m having trouble getting the data from the hash table object within the array.

For example:

get-adcomputer -Filter * -Property Name,OperatingSystem,Enabled,DistinguishedName,IPAddress,DNSHostname | 
Select-Object Name,OperatingSystem,Enabled,DistinguishedName,IPAddress,DNSHostname -First 200 | 
Where-Object { ($_.OperatingSystem -like '*Server*') -and ($_.DistinguishedName -notlike "OU=Disabled_Servers,OU=ComputerAccounts,DC=DOMAIN,DC=ca") -and ($_.Enabled -eq "Enabled")} |
    ForEach-Object -Process { 
        #Populate hashtable to hold the server details
        $ServerDetails['FQDN']=$_.DNSHostname
        $ServerDetails['Enabled']=$_.Enabled

        #Save to the global array
        $EnabledADServers+= $ServerDetails
    }

$ServerDetails ends up with the values I retrieve earlier and $EnabledADServers ends up with one object for each server I retrieved.

I’m having issues understanding how to access the value of specific keys within the hash once it’s in the array.

Kevin,
Welcome to the forum. :wave:t4:

I assume your code is part of a pipeline. But since you did not format it as code there are some characters missing.

So please when you post code, sample data, console output or error messages please format it as code using the preformatted text button ( </> ). Simply place your cursor on an empty line, click the button and paste your code.
Thanks in advance
How to format code in PowerShell.org

And it might be helpful when you post some more of the code. :wink:

Most of the times using the += operator is not a good idea. Instead you should simply output the hashtable variable to the pipeline and collect it with a variable assignment in front of the pipeline.

Thanks, there, that should be easier to understand what I’m doing and how I’m storing the data I collected. The issue comes after I have it - how can I access it.

For example, how can I use the FQDNName value from the stored hash table in the array?

I was thinking that I could use the array of hash tables to open remote connections for all the servers then run the commands on all them. Iterating through a thousand servers to do the same thing over and over is time consuming. Executing the remotely goes much faster but I am having trouble understanding how to get the value from the hash table in the array.

:+1:t4:

A very common and as I think easier way of collecting structured data is a [PSCustomObject].

$EnabledADServers =
Get-ADComputer -Filter * -Property Name, OperatingSystem, Enabled, DistinguishedName, DNSHostname | 
Where-Object { 
    ($_.OperatingSystem -like '*Server*') -and 
    ($_.DistinguishedName -notlike "OU=Disabled_Servers,OU=ComputerAccounts,DC=DOMAIN,DC=ca")
} |
Select-Object -First 200 | 
ForEach-Object -Process { 
    [PSCustomObject]@{
        FQDN    = $_.DNSHostname
        Enabled = $_.Enabled
    }
}

$EnabledADServers

Now you can output or access the collected data as you wish. Either just the names:

$EnabledADServers.DNSHostname

Or just the ones where the property Enabled is true:

$EnabledADServers | Where-Object -Property 'Enabled' -EQ -Value $true

(That’s why I purposly omitted the condition -and ($_.Enabled -eq "Enabled") in the code above :wink: )

That is the easier way to access the data.

My end goal is to run the same set of commands on all the servers remotely. Then retrieve the results from the remote run when it’s completed. I was thinking I wouldn’t know what result came from which server, which is why I was trying to use a hash table to store the results.

I’ll re-work the code to use an array of arrays as I can work with that. I’ll just have to rethink getting retrieving the results.

Thanks for your time.

Of course that’s easily possible when you extend your foreach loop with the querries you need …

....
ForEach-Object -Process { 
    $OS = Get-CimInstance -ClassName CIM_OperatingSystem -ComputerName $($_.samaccountname)
    [PSCustomObject]@{
        FQDN        = $_.DNSHostname
        Enabled     = $_.Enabled
        OS          = $OS.Caption
        InstallDate = $Os.InstallDate
    }
}

You can combine as many different querries for each server as you need.