我正在尝试构建一个从各种来源收集数据的报告文件。 我已经建立了这样的报告结构:
$Data = import-csv "some CSV FILE"
<#
csv file must look like this
hostname,IP
server1,192.168.1.20
#>
然后我正在构建一个数组对象,预先填充&#34;初始值&#34;,然后将它附加到我的$ 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
这完全是我无意识的...... 有人可以澄清我做错了吗?
我在Windows 7上使用PowerShell 5.0。 所有测试都是使用powershell_ise完成的,我没有更改任何powershell默认值
我的预期结果是$ Final Report变量包含扩展内容,而不是我在过程中使用的所有变量......
答案 0 :(得分:0)
似乎经过多次挖掘后我才明白,为什么会发生这种情况。
我使用简单的$ b = $ a赋值,这似乎是浅拷贝的一种形式。所以$ b中的任何变化也会影响对象$ a,反之亦然。
出于我的目的,我需要不同的数据副本,似乎解决方案是做一个深层复制,类似于这篇文章的解决方案: PowerShell copy an array completely
因此,给我想要的结果的工作代码是:
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