GettingStarted
GettingStarted

Reputation: 7605

Multiple column output using a hashtable

I am trying to create a Hash Table that contains 3 columns.

 SERVER_NAME  PROCESS_NAME  SERVER_STATUS   PROCESS_AVAILABLE
 SERVER1      app1.exe      RUNNING         YES
 SERVER1      app2.exe      RUNNING         NO
 SERVER2      app1.exe      OFFLINE         NO
 SERVER2      app2.exe      OFFLINE         NO
 SERVER3      app1.exe      RUNNING         YES
 SERVER3      app2.exe      RUNNING         YES

So far, I've tried this

$SERVERLIST = Get-Content "$PSScriptRoot\servers\serverManager.bin"
$PROCESSMONITOR  = Get-Content "$PSScriptRoot\process\application.bin"

$testList = @{Name=$SERVERLIST;Process=$PROCESSMONITOR}

The list of servers are in the "serverManager.bin" file. This is a CSV file that contains a list of the servers.

The list of processes that I am interested in monitoring are in the "application.bin" file. This is a CSV file that contains a list of the applications (as seen by PowerShell). [see code below]

 Get-Process -ComputerName $server -name $process -ErrorAction SilentlyContinue

I want to build a report which tells an admin which server is running and which process is running from the list that we are interested in monitoring.

I can check if the process is running I can check if a server is online

My question is what do I need to do to get output like what's posted above

Upvotes: 1

Views: 13289

Answers (1)

Matt
Matt

Reputation: 46710

While hashtables play a part in this answer you are not looking for hashtables at all really. Looking at about_hash_tables

A hash table, also known as a dictionary or associative array, is a compact data structure that stores one or more key/value pairs.

While you can nest whatever you want into the value you really are not looking for a hashtable. What I think you want is a custom PowerShell object that contains the results of each of your queries.

Get-Process does take arrays for both -Computer and -Name but they would omit results where either the computer does not exist or the process does not. Since you want that information you need to run a single cmdlet for each computer/process pair.

I use a hashtable only to create each individual "row" which is converted to a PowerShell object and collected as an array. I don't want to confuse but I know this working with at least 2.0 which is why I do it this way.

$SERVERLIST | ForEach-Object{
    $computer = $_
    $PROCESSMONITOR | ForEach-Object{
        $process = $_
        $props = @{
            Server_Name = $computer
            Process_Name = $process
        }

        # Check if the computer is alive. Better this was if $processes is large
        If(Test-Connection $computer -Quiet -Count 1){
            $props.Server_Status = "Running"
            $result = Get-Process -Name $process -ComputerName $computer -ErrorAction SilentlyContinue
            If($result){
                $props.Process_Available = "Yes"
            } else {
                $props.Process_Available = "No"
            }
        } else {
            $props.Server_Status = "Offline"
            $props.Process_Available = "No"
        }

        New-Object -TypeName psobject -Property $props
    }
} | Select Server_Name,Process_Name,Server_Status,Process_Available

So now that we have a proper object you can now use other cmdlets like Where-Object, Sort-Object and etc.

Upvotes: 6

Related Questions