0

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

$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

这对我来说完全是无意的......有人可以澄清我做错了什么吗?

我在 Windows 7 上使用 powershell 5.0。所有测试都是使用 powershell_ise 完成的,我没有更改任何 powershell 默认值

我的预期结果是 $Final Report 变量包含扩展内容,而不是我在过程中使用的所有变量......

4

1 回答 1

1

经过一番挖掘,我似乎在某种程度上理解了为什么会发生这种情况。

我正在使用简单的 $b = $a 分配,这似乎是一种浅拷贝形式。所以 $b 的任何变化也会影响对象 $a ,反之亦然。

出于我的目的,我需要数据的不同副本,似乎解决方案是做一个深拷贝,类似于这篇文章的解决方案: PowerShell copy an array fully

因此,给我所需结果的工作代码将是:

    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
于 2017-02-10T16:05:47.107 回答