当使用notcontains检查数组中的对象时,当它应该为false时说True。这是我的代码。
$SPSecUsers = Get-ADGroupMember Test
$AllLondon = Get-ADGroupMember Test_AllLondon
$SPSecUKUsers = @()
$SPSecUSUsers = @()
foreach ($SPSecUser in $SPSecUsers) {
if ($SPSecUser.distinguishedName -match "DC=uk,DC=company,DC=com") {
$SPSecUKUsers += $SPSecUser
} else {
$SPSecUSUsers += $SPSecUser
}
}
foreach ($UKUser in $AllLondon) {
if ($SPSecUKUsers -notcontains $UKUser) {
Write-Host $UKUser.name -ForegroundColor Green
} else {
Write-Host $UKUser.name -ForegroundColor Red
}
}
每次运行此命令时,$ SPSecUKUsers -notcontains $ UKUser都会为所有用户显示True,即使对象在数组中也是如此。
在调试模式下,我手动进行检查,即使User对象位于数组中,它仍然会显示True。
我甚至将两个组都设置为具有完全相同的用户,但仍然无法正常工作。
答案 0 :(得分:0)
tl; dr
不要将AD用户对象自己存储在数组中,而是使用其.SamAccountName
属性值(通常,选择一个唯一标识对象的属性):
# ...
$SPSecUKUsers += $SPSecUser.SamAccountName
# ...
if ($SPSecUKUsers -notcontains $UKUser.SamAccountName) { # ...
如果想知道为什么存储对象本身不起作用,请参见下一节。
或者-为了更快地查找-使用 hashtable :
$SPSecUKUsers = @{} # initialize hashtabe
# ...
# Create an entry for the object at hand, using its .SamAccountName
# as the entry *key*; you can store the object itself as the entry *value*.
# If all you need are lookups by SAM account name, however, you can just
# use a fixed value such as $true.
$SPSecUKUsers[$SPSecUser.SamAccountName] = $SPSecUser
# ...
if ($SPSecUKUsers.ContainsKey($UKUser.SamAccountName)) { # ...
Olaf和Lee_Daily在评论中暗示,PowerShell的 containment operators(-contains
/ notcontains
和-in
/ -notin
)如果输入的元素是 .NET reference types 的实例,请检查与输入数组的元素是否具有 引用相等性(标识)的比较操作数。 strong>,但[string]
个实例除外,它们被value types对待,并通过
进行了测试
值相等性(等效性)-参见Equality Comparisons。
您可以将集合运算符视为输入数组元素上的隐式循环,使用 -eq
运算符对比较操作数进行测试(或者,如果使用case-敏感变体,例如-ccontains
和-ceq
),根据元素类型使用引用相等或值相等。
重要:由于PowerShell灵活的自动类型转换规则,在-eq
操作中,哪个操作数是LHS很重要。 使用-in
或-contains
意味着隐含的-eq
操作的LHS是要测试的 array元素 ,如下所示示例显示:
# `, 10` creates a single-element array
'0xa' -in , 10 # equivalent of: 10 -eq '0xa' => $true
, 10 -contains '0xa' # ditto
#
10 -in , '0xa' # equivalent of: '0xa' -eq 10 => $false
, '0xa' -contains 10 # ditto
在前2个操作中,LHS为数字([int]
)也将字符串RHS([string]
)强制为数字([int]
),十六进制“数字字符串“ '0xa'
也将转换为带有十进制值[int]
的{{1}}。
在后一个2中,LHS是字符串(10
)强制数字[string]
也变成字符串,并且10
显然与'10'
不匹配
值相等(相等)意味着两个对象具有相同的内容 ,即使具有不同的值类型对象,该内容按照定义存储在不同的存储位置。
例如,'0xa'
和[int]
等数字类型是值类型。根据粗略的经验法则,具有属性的对象通常是引用类型。
您可以检查给定类型的[double]
属性;例如,.IsValueType
返回[int].IsValueType
。
引用相等(同一性)意味着两个值仅在指向内存中的非常相同的对象(即相同的实例)时才被视为相等引用类型。
否则,即使它们表示概念上相同的实体,也将它们视为不相等,这就是您所遇到的情况:对$true
的两个单独调用返回区别对象,即使您(部分)在两种情况下都要求相同的用户(Get-ADUser
返回类型为Microsoft.ActiveDirectory.Management.ADUser
的实例,这是引用类型)。
示例:
Get-ADUser