Powershell dbatools combining result of multiple Get-dbaxxx commands to generate a report I'm new to powershell and dbatools. It is a great tool but when I try to combine the result of few different commands into an array to be exported to csv, it is not providing the intended result. It is only printing the output of first commands. Can someone please help me with joining the result of all three variables? What I'm trying to do is writing a script to automate generating our SQL Server Inventory and Capacity assessment report. 

Here's my code so far:

$Servers = Get-Content 'C:\Users\temp\ServerList.txt'

$reportData = @()

foreach ($Server in $Servers) {

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

    $OSInfo=Get-DbaOperatingSystem -ComputerName MyServer| Select ComputerName, OSVersion, Version, Architecture
    $DiskSPace=Get-DbaDiskSpace -ComputerName MyServer| Select ComputerName, Label, Name, Capacity, Free
    $SQLInstanceInfo=Connect-DbaInstance -SqlInstance MyServer | Select DbaInstanceName, Edition, NetPort, IsClustered, Processors, ProductLevel, ServiceName, 


    $reportData +=$OSInfo
    $reportData +=$DiskSPace
    $reportData +=$SQLInstanceInfo

  }

  else {

    write-host $Server "not connected"
  }
}

Write-Output $reportData | Format-Table
TL;DR
Create a PSCustomObject with the properties of your variables.

PowerShells output formatter uses the first object in the output set as a template for displaying subsequent objects in table format.
If the first object has properties A, B, and C those will be the table headers.
If the second object has only properties D, E, and F then a blank line will be shown.
You can see it for yourself with this example:
$TestResults = @()

$Test1 = [PSCustomObject]@{
    Name = 'Test1'
    Type = 'PSCustomObject'
}
$Test2 = [PSCustomObject]@{
    Name = 'Test2'
    Type = 'PSCustomObject'
}
$Test3 = [PSCustomObject]@{
    Label = 'Test3' # &lt;-- This is &quot;Label&quot;, not &quot;Name&quot;.
    Type = 'PSCustomObject'
}

$TestResults += $Test1
$TestResults += $Test2
$TestResults += $Test3

# Show output:
$TestResults



Option 1 - Calculated Properties (Wouldn't recommend in your scenario):
So, you could rename the properties in your variables to have the same name using calculated properties?
$Test3 | Select-Object @{ Name = 'Name'; Expression = { $_.Label }}, Type


Then when you add this to your array, all the values should show:
$TestResult_02 = @()

$TestResult_02 += $Test1
$TestResult_02 += $Test2
$TestResult_02 += $Test3 | Select-Object @{ Name = 'Name'; Expression = { $_.Label }}, Type

$TestResult_02


Why not this method for your scenario?
All your properties mean separate things.
The Architecture property of $OSInfo doesn't match up with any property of $DiskSpace for example.
Using calculated properties here would likely end up confusing everyone in time.
Option 2 - Creating a PSCustomObject (Would recommend)
It's easy to build up a PSCustomObject type, especially if you know the output of commands or variables in advance as you do in your scenario.
$ResultObject = [PSCustomObject]@{
    Test1_Name = $Test1.Name
    Test1_Type = $Test1.Type
    Test2_Name = $Test2.Name
    Test2_Type = $Test2.Type
    Test3_Name = $Test3.Label
    Test3_Type = $Test3.Type
}

$ResultObject


Using your examples with the information on my machine, we can create the following PSCustomObject
$FullResults = [PSCustomObject]@{
    ComputerName = $OSInfo.ComputerName
    OSVersion = $OSInfo.OSVersion
    Version = $OSInfo.Version
    Architecture = $OSInfo.Architecture
    InstanceName = $SQLInstanceInfo.DbaInstanceName
    Edition = $SQLInstanceInfo.Edition
    NetPort = $SQLInstanceInfo.NetPort
    IsClustered = $SQLInstanceInfo.IsClustered
    Processors = $SQLInstanceInfo.Processors
    ProductLevel = $SQLInstanceInfo.ProductLevel
    ServiceName = $SQLInstanceInfo.ServiceName
    Disks = $DiskSPace
}

$FullResults