所以我的第一个答案是不正确的。我误解了这个问题。这是一个新的例子:
$Props = 'Level-0','Level-1','Level-2','Level-3','Level-4'
$GroupDefs = Import-Csv C:\temp\Book2.csv
For( $i = 0; $i -lt $GroupDefs.Count; ++$i )
{ # Loop through the objects that came from the CSV file...
For( $p = 1; $p -lt $Props.Count; ++$p )
{ # Loop through the known properties...
$Prop = $Props[$p] # Convenience var
$GroupProp = $Props[$p-1] # Convenience var
If( $GroupDefs[$i].$Prop ) {
# If the property is populated then loop backwards from $i-1,
# the group def record just prior to the current one.
$Member = $GroupDefs[$i].$Prop
:Inner For($r = ($i-1); $r -ge 0; --$r)
{
If( $GroupDefs[$r].$GroupProp ) {
# This means you hit the first record behind your current
# position that has the previous property populated. Now
# we know the group...
$Group = $GroupDefs[$r].$GroupProp
Add-DistributionGroupMember -Identity $Group -Member $Member -WhatIf
Break Inner
}
}
}
}
}
通过使用传统的 For 循环,我们可以在其他位置找到值。所以,我解决这个问题的方法是将已知属性的循环嵌套在组定义的循环中。当我找到一个具有值的属性时,我会从$GroupDefs 中的当前位置向后循环,直到找到填充的前一个属性。到那时,我已经设法找到了组和成员,所以我可以运行命令了。
评论更新:
此计划中没有 Dot 采购。使用点引用。如前所述,. 是一个运算符,因为在引用属性之前将计算右侧的值,因此我们可以使用变量或表达式。
假设您正在逐行浏览电子表格。那就是$GroupDefs的外循环。你可以看$i的值,就好像它是一个行#。
现在,对于这些行中的每一行,我想查看一组已知的属性名称中的每一个。所以我们要遍历$Props。如果其中一个属性有值,那么我想查看前面的行以找到最近的上一行,其中填充了上一个属性 ($Prop[$p-1])。例如,如果 Level-2 填充在第 3 行中,我知道我必须回顾第 2、1、0 行才能找到属性 Level-1 的第一个先前值。这部分是最里面的循环,它通过$GroupDefs 数组从当前位置 -1 ($p = ($i-1)) 向后移动到 0。当找到第一个填充的 Level-1 的先前值时,我知道那是组名。
$Member 是一个便利变量。它设置为$GroupDefs[$i].$Prop,因为给定属性的值是我们希望添加到尚未确定组的成员。
注意:$GroupDefs.$i 不会返回任何内容。在任何给定时刻$i 是由循环确定的数字,但它不是$GroupDefs 数组或其中任何对象的属性名称。因此,它既不会从数组本身返回任何属性值,也不会展开(枚举)其中包含的对象的任何属性。
注意:$Prop 的值会随着您循环访问属性而改变,直到在给定名称的属性上找到值。
我知道这很令人困惑,但是如果您逐步查看代码,您会更好地理解发生了什么。首先,试着理解字面上正在做什么。那么代码应该更有意义...