Powershell Select-Object -expandproperty странное поведение, когда ввод является массивом и содержит свойства массива
Я пытаюсь создать файл отчета, собирая данные из разных источников. Я построил структуру отчетности следующим образом:
$Data = import-csv "some CSV FILE"
<#
csv file must look like this
hostname,IP
server1,192.168.1.20
#>
Затем я создаю объект массива, предварительно заполненный "начальными значениями", и присоединяю его к своей переменной $data
$Ids = ('7.1.1.1','7.1.1.2')
$CheckObj= @()
foreach ($id in $IDs) {
$row = "" | Select-Object CheckID,CheckData,CheckDataRaw
$row.CheckID = $id
$row.CheckData = "NotChecked"
$CheckObj+= $row
}
$Data = $Data | Select *,CheckData
$data | % {$_.CheckData = $CheckObj}
Полученный объект:
hostname : server1
ip : 192.168.1.20
CheckData : {@{CheckID=7.1.1.1; CheckData=NotChecked; CheckDataRaw=},
@{CheckID=7.1.1.2; CheckData=NotChecked; CheckDataRaw=}}
Все хорошо, пока я не хочу сделать это:
$FinalReport = $data | Select-Object -Property * -ExpandProperty Checkdata
Я получаю все эти ошибки, которые, скажем, я могу игнорировать...
Select-Object : The property cannot be processed because the property
"CheckData" already exists.
At line:1 char:24
+ ... lReport = $data | Select-Object -Property * -ExpandProperty Checkdata
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (@{hostname=serv...ystem.Objec
t[]}:PSObject) [Select-Object], PSArgumentException
+ FullyQualifiedErrorId : AlreadyExistingUserSpecifiedPropertyExpand,Micro
soft.PowerShell.Commands.SelectObjectCommand
НО, весь набор других переменных изменяется, например:
$data | fl
hostname : server1
ip : 192.168.1.1
CheckData : {@{CheckID=7.1.1.1; CheckData=NotChecked; CheckDataRaw=;
hostname=server1; ip=192.168.1.1}, @{CheckID=7.1.1.2;
CheckData=NotChecked; CheckDataRaw=; hostname=server1;
ip=192.168.1.1}}
а также переменная $CheckObj
$CheckObj
CheckID : 7.1.1.1
CheckData : NotChecked
CheckDataRaw :
hostname : server1
ip : 192.168.1.1
CheckID : 7.1.1.2
CheckData : NotChecked
CheckDataRaw :
hostname : server1
ip : 192.168.1.1
Это совершенно непреднамеренно с моей стороны... Может кто-то уточнить, что я делаю не так?
Я использую PowerShell 5.0 в Windows 7. Все тестирование проводилось с использованием powershell_ise, и я не изменил ни одного из значений по умолчанию PowerShell.
Я ожидаю, что переменная $Final Report будет содержать расширенное содержимое, а не все переменные, которые я использовал в процессе...
1 ответ
Кажется, после еще нескольких копаний я понял, в какой-то степени, почему это происходит.
Я использую простые назначения $b = $a, которые кажутся мелкой копией. Таким образом, любое изменение в $ b также влияет на объект $ a и наоборот.
Для моей цели мне нужны отдельные копии данных, кажется, решение состоит в том, чтобы сделать глубокое копирование, аналогичное решению этого поста: PowerShell полностью копирует массив
Таким образом, рабочий код, который дает мне желаемый результат, будет:
Function Copy-Object ($Source,[switch]$DeepCopy) {
# Serialize and Deserialize data using BinaryFormatter
if ($DeepCopy) {
$ms = New-Object System.IO.MemoryStream
$bf = New-Object System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
$bf.Serialize($ms, $Source)
$ms.Position = 0
#Deep copied data
$Target = $bf.Deserialize($ms)
$ms.Close()
Write-Output $Target
}
Else {
Write-Output $Source
}
}
$Data = "" | select hostname,IP
$data.Hostname = "server1"
$data.IP = "192.168.1.10"
$Ids = ('7.1.1.1','7.1.1.2')
$CheckObj= @()
foreach ($id in $IDs) {
$row = "" | Select-Object CheckID,CheckData,CheckDataRaw
$row.CheckID = $id
$row.CheckData = "NotChecked"
$CheckObj += $row
}
$Data = Copy-Object -source $Data -DeepCopy | Select *,CheckData2
$Data | % {$_.CheckData2 = Copy-Object -source $CheckObj -DeepCopy}
$FinalReport = Copy-Object -source $Data -DeepCopy | Select-Object -Property hostname,IP -ExpandProperty Checkdata2
$FinalReport | ft
выходное значение:
CheckID CheckData CheckDataRaw hostname IP
------- --------- ------------ -------- --
7.1.1.1 NotChecked server1 192.168.1.10
7.1.1.2 NotChecked server1 192.168.1.10