Format-table combining results from multiple commands on same row

Brass Contributor

(I'm new to PowerShell and my understanding is limited so I would appreciate a brief explanation as well as a solution if possible)

 

I've got the following code running successfully to query a list of computers and return various data about them in a table.  However, the data from the various commands run against a particular computer is not appearing on the same row.  Can anyone suggest a way to combine the results for one machine onto a single table row?

 

$hostnames = Get-Content "allpcs.txt"

$output = foreach ($hostname in $hostnames) {
    
    if (Test-Connection -ComputerName $hostname -Count 1 -ErrorAction 'SilentlyContinue') {
    
        Invoke-Command -ComputerName $hostname -ScriptBlock {
            
            Get-WmiObject Win32_ComputerSystem | Select-Object -ExcludeProperty name;
            (Get-ItemProperty -Path "c:\windows\system32\hal.dll").VersionInfo.FileVersion;
            (Get-ItemProperty -Path "C:\Program Files (x86)\Microsoft Office\root\Office16\ONENOTE.EXE").VersionInfo.FileVersion;
            gcim Win32_OperatingSystem | select InstallDate,LastBootupTime;
            Get-PSDrive C | select Free;           
        }
    }
    
    else {

        write-host $hostname "not connected"
    }
}

$output | Format-Table Name,OSver,O365ver,InstallDate,LastBootupTime,Free | Out-File -filepath allpcs.csv -Append

Example output:

 

Name       OSver O365ver InstallDate         LastBootupTime      Free        
----       ----- ------- -----------         --------------      ----        
comp1                                                                   
10.0.16299.371 (WinBuild.160101.0800)
16.0.8431.2110
                         05/10/2018 16:18:59 14/11/2018 09:48:33             
                                                                 40862683136
comp2                                                                    
10.0.16299.371 (WinBuild.160101.0800)
16.0.9126.2259
                         13/08/2018 15:49:28 09/11/2018 07:46:41             
                                                                 436695408640

 

2 Replies

 

Sorry, I didn't have a chance to thoroughly test this yet.

 

What you want is a PowerShell custom object to format the data the way you want. See below.

 

You may find this reference useful: A PowerShell Object Lesson: Part 3

 

---------------------------------------------------------------------------------------------------

 

$hostnames = Get-Content "allpcs.txt"

# create a custom PowerShell object to store specific information
$ComputerInfoObj = [PSCustomObject]@{
    Name = ""
    OSVer = ""
    O365ver = ""
    InstallDate = ""
    LastBootUpTime = ""
    Free = ""
}


$output = foreach ($hostname in $hostnames) {
    
    if (Test-Connection -ComputerName $hostname -Count 1 -ErrorAction 'SilentlyContinue') {
    
        Invoke-Command -ComputerName $hostname -ScriptBlock {
            
            $ComputerInfoObj.Name           = (Get-WmiObject Win32_ComputerSystem).Name
            $ComputerInfoObj.OSVer          = (Get-ItemProperty -Path "c:\windows\system32\hal.dll").VersionInfo.FileVersion
            $ComputerInfoObj.O365ver        = (Get-ItemProperty -Path "C:\Program Files (x86)\Microsoft Office\Office16\ONENOTE.EXE").VersionInfo.FileVersion
            $ComputerInfoobj.Free           = "$([int64]((Get-PSDrive C).Free / 1GB)) GB"
            $ComputerInfoObj.InstallDate    = (Get-CimInstance Win32_OperatingSystem).InstallDate
            $ComputerInfoObj.LastBootUpTime = (Get-CimInstance Win32_OperatingSystem).LastBootUpTime
            
        }
    }
    
    else {

        write-host $hostname "not connected"
    }
}

Write-OutPut $ComputerInfoObj | Format-Table
Write-Output $ComputerInfoObj | ConvertTo-Csv | Out-File allpcs.csv -Append

Thank you, @Darrick the A PowerShell Object Lesson: Part 3 article was helpful.

 

I managed to tweak the code slightly to get my table by putting each new object into an array.  That array could then be presented as a table (and exported to csv).

 

Here is the final, working script:

 

$hostnames = Get-Content 'allpcs.txt'

$allpcs = @()

foreach ($hostname in $hostnames) {

  if (Test-Connection -ComputerName $hostname -Count 1 -ErrorAction 'SilentlyContinue') {

  $OS = Get-WmiObject -Class Win32_OperatingSystem -Computer $hostname

  $pcinfo = [PSCustomObject]@{
  Name = $OS.PSComputerName
  OSVer = (Get-ItemProperty -Path '\\$hostname\c$\windows\system32\hal.dll').VersionInfo.FileVersion
  O365ver = (Get-ItemProperty -Path '\\$hostname\c$\Program Files (x86)\Microsoft Office\root\Office16\ONENOTE.EXE').VersionInfo.FileVersion;
  Free = Invoke-Command -ComputerName $hostname {[math]::Round((Get-PSDrive -Name C | Select-Object -ExpandProperty Free)/1GB,2)}
  InstallDate = $OS.ConvertToDateTime($OS.Installdate)
  LastBootUpTime = $OS.ConvertToDateTime($OS.LastBootUpTime)

  }

  $allpcs += $pcinfo

  }

  else {

  write-host $hostname "not connected"
  }
}

Write-Output $allpcs | Format-Table
Write-Output $allpcs | ConvertTo-Csv | Out-File -filepath 'allpcs.csv'