我有以下脚本:
$serverList = @{
"Server1Name" = @{ "WindowsService1" = "Status"; "WindowsService2" = "Status" };
"Server2Name" = @{ "WindowsService1" = "Status"; "WindowsService2" = "Status" };
"Server3Name" = @{ "WindowsService1" = "Status" };
"Server4Name" = @{ "WindowsService1" = "Status" };
"Server5Name" = @{ "WindowsService1" = "Status" };
"Server6Name" = @{ "WindowsService1" = "Status" }
}
$copy = $serverList.Clone()
foreach ($server in $copy.Keys) {
foreach ($service in $copy[$server].Keys) {
$serviceInfo = Get-Service -ComputerName $server -Name $service
$serverList[$server][$service] = $serviceInfo.Status
}
}
我确保没有修改正在枚举的哈希表,但在运行脚本时仍然收到此错误:
Collection was modified; enumeration operation may not execute.At line:14 char:14
+ foreach ($service in $copy[$server].Keys) {
+ ~~~~~~~~
+ CategoryInfo : OperationStopped: (:) [], InvalidOperationException
+ FullyQualifiedErrorId : System.InvalidOperationException
我在这里读到了这一点:http://blog.matticus.net/2013/11/powershell-clearing-values-within.html 。如果我将代码表单复制到那里,它执行时不会出现错误。
我的问题可能与嵌套的 foreach 循环有关吗?我的代码有错误吗?有人能解释一下吗?
最佳答案
Powershell 不喜欢您修改正在迭代的集合。
一开始,您创建了一个名为 $copy 的克隆来避免此问题。 clone()
是“浅拷贝”,因此每个键引用的对象在副本中是相同的。
在这一行:
$serverList[$server][$service] = $serviceInfo.Status
您修改内部集合 - 您当前正在迭代该集合。
事实上,外部集合从未被修改,仅被引用,因此外部clone()调用是不必要的。相反,您应该克隆内部集合。 像这样的东西(未经测试):
$serverList = @{
"Server1Name" = @{ "WindowsService1" = "Status"; "WindowsService2" = "Status" };
"Server2Name" = @{ "WindowsService1" = "Status"; "WindowsService2" = "Status" };
"Server3Name" = @{ "WindowsService1" = "Status" };
"Server4Name" = @{ "WindowsService1" = "Status" };
"Server5Name" = @{ "WindowsService1" = "Status" };
"Server6Name" = @{ "WindowsService1" = "Status" }
}
foreach ($server in $serverList.Keys) {
$copy = $serverList[$server].clone();
foreach ($service in $copy.Keys) {
$serviceInfo = Get-Service -ComputerName $server -Name $service
$serverList[$server][$service] = $serviceInfo.Status
}
}
关于loops - 修改未枚举的对象时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21885139/