What you're hoping to do it basically a 'join'. Be it CSV, CLIXML, JSON, or any set of objects, you can do build a basic join in a couple of ways.
Assuming that there is not a "key" row you could join on, and you're just joining each row in order.
# Create a hashtable or [Ordered] hashtable to keep track of each file
$fileData = [Ordered]@{}
# We'll need to know the maximum number of rows, so set it to zero.
$MaxRowCount = 0
# Walk over each file
foreach ($csvFile in (Get-ChildItem "$dir\*.csv")) {
# Import the CSV, using the array operator force it into a list.
$csvData = @(Import-Csv $csvFile)
# Put it into our table
$fileData[$csvFile] = $csvData
if ($fileData[$csvFile].Length -gt $MaxRowCount) {
$maxRowCount = $fileData[$csvFile].Length
}
}
# Now, we need to go row-by-row and join our data
# In PowerShell, you can assign the results of a for statement.
# So we can just walk thru our loop and let it populate the data
# (though, once again, we're using to array operator to force it into an array)
$joinedData =
@(for ($rowNumber = 0 ; $rowNumber -lt $maxRowCount; $rowNumber++) {
# Create an ordered hashtable for the new data
$newRow = [Ordered]@{}
# Walk thru each file
foreach ($filePath in $fileData.Keys) {
# and get the row from the file.
$fileRow = $fileData[$filePath][$rowNumber]
# Every object in PowerShell wrapped in a .PSObject
# this lets us walk the properties of each row
foreach ($prop in $fileRow.PSObject.Properties) {
# copy the data into the new output
# (the last file will 'win' when property names collide)
$newRow[$prop.Name] = $prop.Value
}
}
# now, we turn our row into an object
[PSCustomObject]$newRow
})
$joinedData | Export-Csv .\Joined.csv
If you wanted to use a key property to join rows instead, please clarify the question and I can provide a similar answer (you'll be going thru key value by key value, not row by row).
Also, again, the object's don't have to have come from a CSV file. You could easily swap out Import-CSV for Import-CliXml, or, say, Import-Excel (from the module ImportExcel).