Powershell 当我将PS脚本存储在变量中时,为什么会得到不同的结果?

Powershell 当我将PS脚本存储在变量中时,为什么会得到不同的结果?,powershell,powershell-4.0,Powershell,Powershell 4.0,我制作了一个Powershell脚本,它在字符串数组上执行foreach并只收集其中的一些信息。 代码如下: begin { $IMAGELIST = @( "IMAGE Srv01 something something something Srv01_999888777 something" "FRAG 1 something something" "FRAG 2 something something" ) } process { f

我制作了一个Powershell脚本,它在字符串数组上执行foreach并只收集其中的一些信息。 代码如下:

begin {
    $IMAGELIST = @(
    "IMAGE Srv01 something something something Srv01_999888777 something"
    "FRAG 1 something something"
    "FRAG 2 something something"
    )
}   

process {
    foreach ($LINE in $IMAGELIST) {
        if ($LINE.StartsWith("IMAGE")) {
            $IMAGELINE = $LINE.split()
            $BKP_OBJ = [pscustomobject]@{
                Server=$IMAGELINE[1]
                Id=$IMAGELINE[5]
            }
        }

        elseif ($LINE.StartsWith("FRAG")) {
            $FRAGLINE = $LINE.split()
            $BKP_OBJ | Add-Member -Force @{
                CopyNumber = $FRAGLINE[1]
            }
            Write-Output -InputObject $BKP_OBJ
        }
    }
}
运行脚本时,我有一个输出,其中有两个具有不同CopyNumber值的对象(预期结果):

如果我尝试将输出存储在变量中,我会得到相同的CopyNumber(不是预期的结果):


我做错了什么?

我想你想要这样的东西

begin {
    $BKP_OBJ = $null
    $IMAGELIST = @(
    "IMAGE Srv01 something something something Srv01_999888777 something",
    "FRAG 1 something something",
    "FRAG 2 something something"
    )
}   

process {
    $Ximglist = @()
    $Xfrglist = @()
    foreach ($LINE in $IMAGELIST) {
        if ($LINE.StartsWith("IMAGE")) {
            $Ximglist += $LINE
        }
        elseif ($LINE.StartsWith("FRAG")) {
            $Xfrglist += $LINE
        }
    }
    foreach ($Ximg in $Ximglist) {
        $Xfrglist | % {($_.split())[1]} | % {$BKP_OBJ = [pscustomobject]@{
                    Server= ($Ximg.Split())[1]
                    Id= ($Ximg.Split())[5]
                    CopyNumber=$_
                }; 
                Write-Output $BKP_OBJ}
        }
    }

只生成一个对象,修改并输出两次。赋值语句首先使其完成,然后再显示任何输出。指向两个输出的指针相同。(.\BkpScript)将执行相同的操作

cat myscript.ps1

$a = [pscustomobject]@{name='Joe'}
$a
$a.name = 'John'
$a


./myscript      

name
----
Joe
John


(./myscript)  # or ./myscript | sort

name
----
John
John

该代码将创建一个新对象,无论何时输出/管道:

begin {
    $IMAGELIST = @(
    "IMAGE Srv01 something something something Srv01_999888777 something"
    "FRAG 1 something something"
    "FRAG 2 something something"
    )
}   

process {
    $Server = ""
    $Id = ""
    $CopyNumber = 0
    foreach ($LINE in $IMAGELIST) {
        if ($LINE.StartsWith("IMAGE")) {
            $IMAGELINE = $LINE.split()
            $Server=$IMAGELINE[1]
            $Id=$IMAGELINE[5]
        } elseif ($LINE.StartsWith("FRAG")) {
            $FRAGLINE = $LINE.split()
            $CopyNumber = $FRAGLINE[1]
            Select-Object @{n='Server'; e={$Server}}, @{n='Id'; e={$Id}}, @{n='CopyNumber'; e={$CopyNumber}} -InputObject ''
        }
    }
}
输出看起来像您在问题中所期望的:


您可以将
$BKP\u OBJ
保存到一个变量(例如
$ARR\u BKP\u OBJ
)中,以便以后使用。通过执行
$ARR\u BKP\u OBJ=@()
$ARR\u BKP\u OBJ+=$BKP\u OBJ
。我尝试先将$BKP\u OBJ添加到数组中,但是当我试图将脚本的输出存储到$MyVar变量时,我得到了同样的意外结果,认为图像和FRAG字符串是一组信息,在第二次中,我不能在两个单独的数组中进行处理,因为我可以有多个信息集。例如,“IMAGE Srv01 something something Srv01_99988777 something”FRAG 1 something“FRAG 2 something”IMAGE Srv02 something Srv02_456734231 something“FRAG 1 something”FRAG 2 something“FRAG 2 something”听起来像是要使用嵌套的
foreach
?或者(像我的解决方案一样)在
Foreach
语句中使用
Foreach对象(=
%
)。您能告诉我们一些有关您尝试使用此脚本解决的问题的更多信息吗?例如,它包含了很多东西来为管道化做好准备,但我不明白为什么。结果你想要什么?对象列表、字符串或仅在终端上输出?什么是
$FRAGLINE
?您将它用作数组,但它是在哪里定义的?此外,如果第一次测试失败,将不会有对象添加
CopyNumber
属性。问题的根本原因是,您在案例1中创建了一个对象,然后在案例2中对其进行更改,而不是复制它。因此,对象的所有“快照”都将是指向上次修改版本的指针。通常,$IMAGELIST是由外部命令输出提供的字符串数组。外部命令为每个唯一记录提供三行或更多行(第一行始终是IMAGE,其他行不止一个FRAG)对于每个唯一记录,我需要使用IMAGE string中的一些信息和FRAG string中的一些信息创建一个对象@托马斯:你说的话听起来很有道理,但我不能完全理解。在你看来,我应该如何改变剧本?@karnak请看下面我的答案。
cat myscript.ps1

$a = [pscustomobject]@{name='Joe'}
$a
$a.name = 'John'
$a


./myscript      

name
----
Joe
John


(./myscript)  # or ./myscript | sort

name
----
John
John
begin {
    $IMAGELIST = @(
    "IMAGE Srv01 something something something Srv01_999888777 something"
    "FRAG 1 something something"
    "FRAG 2 something something"
    )
}   

process {
    $Server = ""
    $Id = ""
    $CopyNumber = 0
    foreach ($LINE in $IMAGELIST) {
        if ($LINE.StartsWith("IMAGE")) {
            $IMAGELINE = $LINE.split()
            $Server=$IMAGELINE[1]
            $Id=$IMAGELINE[5]
        } elseif ($LINE.StartsWith("FRAG")) {
            $FRAGLINE = $LINE.split()
            $CopyNumber = $FRAGLINE[1]
            Select-Object @{n='Server'; e={$Server}}, @{n='Id'; e={$Id}}, @{n='CopyNumber'; e={$CopyNumber}} -InputObject ''
        }
    }
}
PS C:\Users\db\Desktop> .\test.ps1

Server Id              CopyNumber
------ --              ----------
Srv01  Srv01_999888777 1
Srv01  Srv01_999888777 2


PS C:\Users\db\Desktop> $myvar = .\test.ps1
PS C:\Users\db\Desktop> $myvar

Server Id              CopyNumber
------ --              ----------
Srv01  Srv01_999888777 1
Srv01  Srv01_999888777 2