PowerShell从列表中删除脱机计算机

PowerShell从列表中删除脱机计算机,powershell,loops,arraylist,foreach,Powershell,Loops,Arraylist,Foreach,我有一个脚本,我想在机器列表上执行测试连接,然后从列表中删除脱机机器。这就是我所拥有的: [System.Collections.ArrayList]$Systems = Get-Content -Path C:\temp\test.txt Foreach ($System in $Systems){ if ($false -eq (Test-Connection -CN $System -Count 1 -Quiet)) { $Systems.Remove("$System")

我有一个脚本,我想在机器列表上执行
测试连接
,然后从列表中删除脱机机器。这就是我所拥有的:

[System.Collections.ArrayList]$Systems = Get-Content -Path C:\temp\test.txt

Foreach ($System in $Systems){
  if ($false -eq (Test-Connection -CN $System -Count 1 -Quiet)) {
    $Systems.Remove("$System")
  } 
}
$Systems
此操作失败,出现以下错误:

收集被修改;枚举操作不能执行。在 C:\temp\test.ps1:3字符:10+Foreach($Systems中的系统){~~~~~~~ +类别信息:OperationsStopped:(:)[],InvalidOperationException+FullyQualifiedErrorId:System.InvalidOperationException


当同一个集合(准确地说,是)上正在进行枚举时,您不能修改集合(
$Systems
)。与其从现有列表中删除脱机计算机,不如将联机计算机添加到新列表中

[System.Collections.ArrayList]$Systems=获取内容-路径C:\temp\test.txt
[System.Collections.ArrayList]$OnlineSystems=新对象-TypeName“System.Collections.ArrayList”
Foreach($系统中的系统){
if($true-eq(测试连接-CN$System-Count 1-Quiet)){
$OnlineSystems.Add(“$System”)
} 
}
$OnlineSystems
请注意,当表达式的计算结果已经是布尔值时,不需要将其与布尔值进行比较,也不需要对已经是
[string]
的变量使用字符串插值,因此可以将
Foreach
循环体简化为

if(测试连接-CN$System-计数1-安静){
$OnlineSystems.Add($System)
} 
完全避免枚举冲突的更简洁的代码是使用管道和

[String[]$OnlineSystems=@($Systems | Where Object{Test Connection-CN$\ Count 1-Quiet})

之所以会发生这种情况,是因为不允许在迭代集合时修改集合。其根本原因有点复杂,但也有其他原因

若要更改集合,
foreach
将不起作用,但
for
循环起作用。ArrayList的
RemoveAt()
将按索引删除元素。就像这样

for($i = 0; $i -lt $Systems.Count;  ++$i) {
    if( -not (Test-Connection -CN $systems[$i] -Count 1 -Quiet)) {
        $systems.RemoveAt($i)
    }
}

谢谢大家!这里有这么多选项,我现在有了一个解决方案。我现在还学到了在迭代集合时修改集合是不允许的!