我运行了以下代码来查询AD的第一个或第二个名称。如果我输入";conor";作为输入我得到包含两个用户的预期结果;timms";(同一用户的姓氏(我得到以下错误:Method invocation failed because [Microsoft.ActiveDirectory.Management.ADPropertyValueCollection] does not contain a method named 'op_Subtraction'.
$exists = $true
while ($exists -eq $true) {
$search = Read-Host -Prompt "Enter first name or surname name of user"
$results = Get-ADUser -Filter "Name -like '*$search*'"
if ($results) {
Write-Output "You're in one"
for ($i = 0; $i -le $results.count - 1; $i++) {
$i
$results[$i] | Select-Object Name, SamAccountName | Format-Table
}
}else {
Write-Host "Name does not match any of the users in domain"
$exists = $false
}
}
以conor作为输入的输出:
Enter first name or surname name of user: conor
You're in one
0
Name SamAccountName
---- --------------
Conor Timms Conor.Timms
1
Name SamAccountName
---- --------------
Conor Admin ConorAdmin
以timms作为输入的输出:
Enter first name or surname name of user: timms
You're in one
InvalidOperation:
Line |
7 | for ($i = 0; $i -le $results.count - 1; $i++) {
| ~~~~~~~~~~~~~~~~~~~~~~~~~
| Method invocation failed because [Microsoft.ActiveDirectory.Management.ADPropertyValueCollection] does not contain a method named 'op_Subtraction'.
Enter first name or surname name of user:
根据错误格式,您似乎在PowerShell 7+中执行此操作。如果是这样,它可能正在加载一个隐式会话,因此可能会序列化对象,从而剥离方法。不管怎样,都要记住这一点。
也就是说,即使使用常规数组,也不必执行-le $array.Count -1
。只要条件为true,循环就会运行,因此在基于[0]
的数组中,条件$i -lt $Array.Count
将保持完全为true,直到超出边界。因此,一般来说,它更简单,很可能解决这个问题。
注:@MathiasRJessen在他的评论中也暗示了同样的意思。
$exists = $false
while ( !$exists ) {
$search = Read-Host -Prompt "Enter first name or surname name of user"
$results = @(Get-ADUser -Filter "Name -like '*$search*'")
if ($results) {
Write-Output "You're in one"
for ($i = 0; $i -lt $results.count; $i++) {
$i
$results[$i] | Select-Object Name, SamAccountName | Format-Table
}
}else {
Write-Host "Name does not match any of the users in domain"
$exists = $true
}
}
注意:我还将$exists
的初始值更改为false。我只是觉得这是一种比较典型的做法。
上面与@JoseZ的注释结合在一起,将Get-ADUser
命令封装在数组子表达式中,这样就可以保证数组结果。否则,在只有1个结果的情况下,将返回标量。
注意:使用ForEach
构造之一可能更容易处理循环挑战。
$exists = $false
while ( !$exists ) {
$search = Read-Host -Prompt "Enter first name or surname name of user"
$results = Get-ADUser -Filter "Name -like '*$search*'"
if ($results) {
Write-Output "You're in one"
ForEach( $Result in $results )
{
$result | Select-Object Name, SamAccountName | Format-Table
}
}else {
Write-Host "Name does not match any of the users in domain"
$exists = $true
}
}
在这种情况下,您不需要使用传统的For
循环,无论返回标量还是数组都无关紧要。
将$results = Get-ADUser -Filter "Name -like '*$search*'"
更改为$results = @(Get-ADUser -Filter "Name -like '*$search*'")
解决了此问题。
原因是,如果查询返回一个对象,那么它将被存储为一个对象。如果结果返回2或更多,则将它们存储为数组。
感谢@JosefZ