Проблема в том, что вы обновляете один и тот же объект, $Table
, снова и снова и добавляете ссылки на этот же объект в выходной массив, $ToWrite
- все элементы которогопоэтому в конечном итоге указываем на единственный объект $Table
, значения свойств которого в этой точке содержат значения, которые были назначены в итерации last .
Проблема подробно описана в этот ответ , в котором показано возможное решение с использованием пользовательских классов , доступных в PowerShell v5 и более поздних версиях.
Решение без пользовательских классов требует от вас клон ваш пользовательский $Table
объект в каждой итерации :
# Create a new instance with the same properties:
$Table = $Table.psobject.Copy()
Примечание : этот метод клонирования работает только так, как ожидается с пользовательских объектов , т. Е. Экземпляров [System.Management.Automation.PSCustomObject]
, таких как созданные с помощью Select-Object
командлета и литерального синтаксиса [pscustomobject] @{ ... }
При этом , поскольку вы присваиваете все свойства вашего пользовательского объекта вВ вашем цикле нет смысла создавать шаблон объект заранее - вместо этого просто используйте буквальный синтаксис создания пользовательских объектов [pscustomobject] @{ ... }
(PSv3 +) внутри цикла , который неявно создает новый экземпляр в каждой итерации .
Кроме того, ваше решение может быть оптимизировано, поскольку оно и проще, и эффективнеечтобы PowerShell мог создавать массивы для вас, просто собирая выходные данные команд, которые выводят несколько объектов в переменную .
Вот упрощенный пример, который объединяет все это:
# Loop over the input and instantiate a new custom object
# in each iteration, then let PowerShell collect the results
# in array variable $ToWrite
[array] $ToWrite = 1..3 | ForEach-Object {
# Instantiate and output a new custom object in each iteration.
[pscustomobject] @{
PropA = "ValueA-$_"
PropB = "ValueB-$_"
}
}
# Output the resulting array
$ToWrite
Примечание. Ограничение типа [array]
необходимо только в том случае, если необходимо убедиться, что $ToWrite
является всегда массивом;без него, если бы произошла просто итерация цикла single и, следовательно, выходной объект, $ToWrite
сохранял бы этот выходной объект как есть, а не упакованный в массив (это поведение является фундаментальным для конвейера PowerShell).
Выше приведено следующее, показывающее, что были созданы различные объекты:
PropA PropB
----- -----
ValueA-1 ValueB-1
ValueA-2 ValueB-2
ValueA-3 ValueB-3