This code...
$BIOSSerialNumber = @{name='BIOSSerialNumber';expression={Get-WmiObject -class Win32_BIOS -computername $computerlist | Select-Object -ExpandProperty SerialNumber}}
... collects all the Bios Serial Numbers from all of the computers in $computerlist and puts them into one array... thats why you get {?????H1,?????D1} etc
The code doesn't try and match the BIOS data with the Operating System data
I would re-structure the code like this...
$OSData=Get-WmiObject -class Win32_OperatingSystem -computername $computerlist
$BIOSData=Get-WmiObject -class Win32_BIOS -computername $computerlist
$CombinedData=@()
$BIOSData | foreach-object{
$computername=$_.__Server
$CombinedData+=New-Object PSObject -Property @{
'ComputerName'=$computername;
'BiosSerialNumber'=$_.SerialNumber;
'ServicePack'=($OSData | Where{$_.CSName -eq $computername}).CSDVersion;
'OperatingSystem'=($OSData | Where{$_.CSName -eq $computername}).Caption
}
}
$CombinedData
Does that make sense?