Forum Discussion

Reinier SPRUIJT's avatar
Reinier SPRUIJT
Brass Contributor
Nov 15, 2018

Format-table combining results from multiple commands on same row

(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

 

  • Darrick's avatar
    Darrick
    Brass Contributor

     

    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

    • Reinier SPRUIJT's avatar
      Reinier SPRUIJT
      Brass Contributor

      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'