PowerShell - 不在forEach循环中创建Jagged数组

时间:2015-11-19 11:52:32

标签: arrays powershell foreach

因此,我在PowerShell(v3)中通过forEach循环枚举并将正在评估的变量以及Test-Connection结果添加到数组中时遇到问题。我正在尝试使$ arrPing成为一个多维数组,因为这将使我更容易在后面的脚本中过滤和处理对象,但我遇到了代码问题。

我的代码如下所示:

$arrPing= @();
$strKioskIpAddress= (Get-WmiObject Win32_NetworkAdapterConfiguration | Where-Object { $_.IPAddress -ne $null }).ipaddress

...FURTHER DOWN THE CODE...

$tmpIpAddress= Select-Xml -Path $dirKioskIpAddresses -XPath '//kiosks/kiosk' | Select-Object -ExpandProperty Node

forEach ( $entry in $tmpIpAddress )
    {
    if ( $entry -ne $strKioskIpAddress )
        {
        $result= Test-Connection -ComputerName $entry -Count 1 -BufferSize 16 -Quiet -ErrorAction SilentlyContinue
        $arrPing+= @($entry,$result);
        }
    }

但是当我显示$ arrPing变量的内容时,我得到以下输出:

PS H:\Documents\PowerShell Scripts> $arrPing
10.216.1.134
True
10.216.1.139
True
10.216.23.230
True
10.216.23.196
False
10.216.23.23
False

谁能告诉我哪里出错了?我有一种感觉,这种情况正在发生,因为我处于forEach循环中,但我不能肯定地说......

2 个答案:

答案 0 :(得分:3)

我会使用PSCustomObject

来简化它
$Ping = foreach ($Entry in $tmpIpAddress) {
    if ($Entry -ne $strKioskIpAddress) {
        $TestParams = @{
            ComputerName = $Entry 
            Count        = '1'
            BufferSize   = '16'
            Quiet        = $true
            ErrorAction  = 'SilentlyContinue'
        }
        $Result = Test-Connection @TestParams
        [PSCustomObject]@{
            Entry = $Entry
            Result = $Result
        }
    }
}

$Ping

为了避免一长串参数,我使用了一种名为splatting的技术。

答案 1 :(得分:2)

您正在看PowerShell如何展开数组。变量如设计:一个大数组。但是,PowerShell在显示这些元素时会将每个元素放在自己的行上。如果您不希望这样,特别是如果您要使用此数据将用于过滤掉不在网络上的计算机,那么您应该使用PowerShell对象。

if ( $entry -ne $strKioskIpAddress ){
    $objPing += New-Object -TypeName psobject -Property @{
        Entry = $entry
        Result = Test-Connection -ComputerName $entry -Count 1 -BufferSize 16 -Quiet -ErrorAction SilentlyContinue
    }
}

而不是那些我将继续并使用更加管道友好的不同foreach构造。这样,如果您需要在其他位置使用此输出,则可以使用其他cmdlet,如Export-CSV。还有谎言PetSerAl说

  

[Y]你不应该使用数组加法运算符并逐个添加元素。它[将]创建[a]新数组(因为数组不可调整大小)并在每次操作时复制旧的数组元素。

$tmpIpAddress | Where-Object{$_ -ne $strKioskIpAddress} | ForEach-Object{
    New-Object -TypeName psobject -Property @{
        Entry = $_
        Result = Test-Connection -ComputerName $_ -Count 1 -BufferSize 16 -Quiet -ErrorAction SilentlyContinue
    }
} | Export-CSV -NoTypeInformation $path

if现在因为您使用它而将该逻辑移动到Where-Object,因此无论如何都会过滤掉某些记录,因此Where-Object是多余的。这就是[pscutomobject]的好处。

以上代码适用于PowerShell 2.0。如果您使用的是3.0或更高版本,请使用[ordered]$tmpIpAddress | Where-Object{$_ -ne $strKioskIpAddress} | ForEach-Object{ [psobject][ordered] @{ Entry = $_ Result = Test-Connection -ComputerName $_ -Count 1 -BufferSize 16 -Quiet -ErrorAction SilentlyContinue } } | Export-CSV -NoTypeInformation $path

file = io.BytesIO()
k.get_contents_to_file(file)