我有这个问题很长一段时间,只要我认为它会输出它没有输出的所有数据。
示例:
$groups = "group1","Group2","Group3" # to be excluded
foreach ($group in $groups) {
$dns = (Get-ADGroup "$Group").DistinguishedName
}
Write-Host $dns
将仅输出一个组的专有名称,但如果同时输出
(Get-ADGroup "$Group").DistinguishedName | Out-File c:\list.txt
我将获得所有3.如果我尝试从阵列中获取用户,那么`Get-ADUser也是如此。
任何人都有真正的解决方案吗?
答案 0 :(得分:2)
PowerShell并不会因为你的意愿而神奇地创建一个数组。由于$dns
从一开始就不是一个数组,所以你的代码会在每次迭代时替换它的值,所以你最终只得到循环结束后的最后一个值。
您有2种方法可以解决此问题:
在循环之前将$dns
定义为数组,并在循环内附加到该数组。
$dns = @()
foreach ($group in $groups) {
$dns += (Get-ADGroup "$Group").DistinguishedName
}
虽然几乎每个人似乎都是这样做的,但出于性能原因,该方法 NOT WOMMENDED 。附加到数组是很昂贵的,因为它实际上创建了一个大小增加的新数组,移动所有现有元素并将新元素放入新的空闲插槽中,然后替换原始数组。
在循环内输出结果,并在变量中收集整个循环输出。
$dns = foreach ($group in $groups) {
(Get-ADGroup "$Group").DistinguishedName
}
这种方法比在循环中附加方法具有明显更好的性能。但是,值得注意的是,如果循环产生零个或一个元素,结果将是$null
或简单值,而不是数组。您可以通过将循环放在数组构造运算符中来强制它到数组:
$dns = @(foreach ($group in $groups) {
(Get-ADGroup "$Group").DistinguishedName
})
附录:正如@Clijsters在评论中提到的那样,使用.Net集合而不是基本的PowerShell数组实际上是第三种解决此问题的方法:
$dns = New-Object System.Collections.ArrayList
foreach ($group in $groups) {
$dns.Add((Get-ADGroup "$Group").DistinguishedName) | Out-Null
}
附加到集合远比附加到PowerShell数组要便宜。但是,实例化集合会有一些开销。只需在变量($dns = foreach (...) {...}
)中收集循环输出,即可获得最佳性能。
答案 1 :(得分:1)
问题是您的Write-Host
$groups = "Group1", "Group2", "Group3"
foreach ($group in $groups) {
$dns = (Get-ADGroup $group).DistinguishedName
Write-Host $dns # <--- it's inside, now!
}
这将为每个组写出值,而不仅仅是 last 。