在powershell作业中追加到数组

vmpqdwk3  于 2023-03-08  发布在  Shell
关注(0)|答案(2)|浏览(160)

我找到了一段代码,它可以同时ping通所有系统,比我遇到过的任何其他工作示例都要好。这东西可以一行一行地读取一个装满主机的文件,然后同时ping它们,但是我怎么把那些最大的添加到我的$online数组中呢?我试着添加到true块中,但是没有用。我只是想把$online += $pc粘在某个地方。任何帮助都将不胜感激。谢谢。

$online = @()
$pc = Get-Content C:\servers.txt 
$pc | ForEach-Object { Test-Connection -ComputerName $_ -Count 1 -AsJob } | Get-Job | Receive-Job -Wait | Select-Object @{Name='ComputerName';Expression={$_.Address}},@{Name='Reachable';Expression={if ($_.StatusCode -eq 0) { $true } else { $false }}} | ft -AutoSize
niwlg2el

niwlg2el1#

您可以存储作业的结果,然后按Reachable进行过滤。我还稍微简化了您的代码,并添加了-AutoRemove,我认为它对于在完成作业时处理作业非常重要。

$result = Get-Content C:\servers.txt | ForEach-Object {
    Test-Connection -ComputerName $_ -Count 1 -AsJob
} | Receive-Job -Wait -AutoRemoveJob | ForEach-Object {
    [pscustomobject]@{
        ComputerName = $_.Address
        Reachable    = $_.StatusCode -eq 0
    }
}

$online = $result | Where-Object Reachable

# if you want just the `ComputerName` values, you can do
$online = $result | Where-Object Reachable | ForEach-Object ComputerName

# or easier, using member-access enumeration and `.Where` method
$online = $result.Where{ $_.Reachable }.ComputerName

如果您想在枚举过程中将结果分组为Reachable和Not Reachable,则可以使用一个hash table包含2个List<T> values

$result = @{
    Online  = [System.Collections.Generic.List[object]]::new()
    Offline = [System.Collections.Generic.List[object]]::new()
}

Get-Content C:\servers.txt | ForEach-Object {
    Test-Connection -ComputerName $_ -Count 1 -AsJob
} | Receive-Job -Wait -AutoRemoveJob | ForEach-Object {
    $obj = [pscustomobject]@{
        ComputerName = $_.Address
        Reachable    = $_.StatusCode -eq 0
    }

    if($obj.Reachable) {
        return $result['Online'].Add($obj)
    }
    
    $result['Offline'].Add($obj)
}

$result.Online.ComputerName # => has all reachable records
rjee0c15

rjee0c152#

我相信这里的问题是管道ft -autosize。
尝试在if/else语句后按如下所示使用管道:

| ForEach-Object {
    if ($_.Reachable -eq $true) {
        $online += $_.ComputerName
    }
}

然后,如果您想查看结果,您可以随时执行以下操作:

$online | ft -AutoSize

我还建议你使用更好的格式,因为一行字不容易阅读。试试这样的格式:

$online = @()
$pc = Get-Content C:\servers.txt 
$pc | ForEach-Object { 
    Test-Connection -ComputerName $_ -Count 1 -AsJob 
} | Get-Job | Receive-Job -Wait | 
Select-Object @{Name='ComputerName';Expression={$_.Address}},@{Name='Reachable';Expression={
    if ($_.StatusCode -eq 0) { 
        $true 
    } else { 
        $false 
    }
}} | ForEach-Object {
    if ($_.Reachable -eq $true) {
        $online += $_.ComputerName
    }
}
$online | ft -AutoSize

相关问题