当输入是数组并包含数组属性时,Powershell Select-Object -expandproperty奇怪的行为

时间:2017-02-08 10:50:06

标签: arrays powershell object select-object

我正在尝试构建一个从各种来源收集数据的报告文件。 我已经建立了这样的报告结构:

$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变量包含扩展内容,而不是我在过程中使用的所有变量......

1 个答案:

答案 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