A slightly different approach here. Loop through your collection, for each set find the count for each property and select the highest count. Run that set through that many loops, and on each loop create a custom object where each property checks to see if it is an array. If it is it iterates into that array, if it is not it checks if this is the first round of custom objects and returns the value, else it returns a blank. The output is what you are looking for, and -AutoSize for FT works perfectly.
First I made a collection similar to yours:
$col = @(
(New-Object –TypeName PSObject –Prop @{'id'='01';'name'='a';'items'=@(1,2,3);'others'=@('SampleA1','SampleA2')}),
(New-Object –TypeName PSObject –Prop @{'id'=@('02a','02b');'name'='b';'items'=@(1,2,3);'others'=@('SampleB1','SampleB2','SampleB3','SampleB4','SampleB5')}),
(New-Object –TypeName PSObject –Prop @{'id'='03';'name'=@('c1','c2');'items'=@(1,2,3);'others'='SampleC'})
)
Then I ran that through my suggested code:
$Col|%{
$Current = $_
$Members = $_|GM|?{$_.MemberType -match "Property"}|Select -ExpandProperty Name
$Rows = ($Members|%{$current.$_.count}|sort -Descending|Select -First 1)-1
For($i=0; $i -le $Rows;$i++){
$LoopObject = New-Object PSObject -Property @{$($Members[0]) = if($Current.$($Members[0]).count -gt 1){$Current.$($Members[0])[$i]}else{if(!($i -gt 0)){$Current.$($Members[0])}else{$Null}}}
If($Members.Count -gt 1){
$Members[1..$Members.count]|%{
Add-Member -InputObject $LoopObject -MemberType NoteProperty -Name $_ -Value $(if($Current.$_.count -gt 1){$Current.$_[$i]}else{if(!($i -gt 0)){$Current.$_}else{$Null}})
}
}
$LoopObject
}
}|FT ID,Name,Items,Others -AutoSize
It gave me this output:
id name items others
-- ---- ----- ------
01 a 1 SampleA1
2 SampleA2
3
02a b 1 SampleB1
02b 2 SampleB2
3 SampleB3
SampleB4
SampleB5
03 c1 1 SampleC
c2 2
3
Edit: Ok, updated my code. It no longer cares what array you throw at it, how many properties it has, or how many properties those properties have. Just so long as the collection given it contains only strings and/or arrays it will output the desired collection of objects you want, like my output noted above.