具有对象集合的 PowerShell 包含运算符

PowerShell containment operators with collections of objects

在对象集合(在本例中,由 ActiveDirectory 模块命令行开关创建)上使用 PowerShell 中的包含运算符(例如,-contains、-notcontains、-in)时,我没有观察到预期结果。操作员似乎无法检测到集合中我确定匹配的对象。

在下面的示例中,我什至使用 compare-object commandlet 来证明元素确实匹配。


$PSVersionTable | Format-Table

$adusers_list = (get-aduser -id fooboss -properties directreports).directreports |%{ Get-ADUser -Identity $PSItem } 

$target_aduser = get-aduser -id jrw 


# This use of containing operators seems very similar to the example presented in documentation:
# https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_comparison_operators?view=powershell-6#containment-operators
# Here comes the unexpected results:
$adusers_list -contains $target_aduser

$target_aduser -in $adusers_list 

#And yet...
$adusers_list |%{
    if ($_.samaccountname -eq "jrw") {
        write-output "Contrary to what the contains operators told us, here it is: $($_.samaccountname)"
        Write-output "also, compare-object says:"
        compare-object $_ $target_aduser
    }
}

和输出:



Name                           Value                                                                                                                                                      
----                           -----                                                                                                                                                      
PSVersion                      5.1.18362.145                                                                                                                                              
PSEdition                      Desktop                                                                                                                                                    
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}                                                                                                                                    
BuildVersion                   10.0.18362.145                                                                                                                                             
CLRVersion                     4.0.30319.42000                                                                                                                                            
WSManStackVersion              3.0                                                                                                                                                        
PSRemotingProtocolVersion      2.3                                                                                                                                                        
SerializationVersion           1.1.0.1                                                                                                                                                    


False
False
Contrary to what the contains operators told us, here it is: jrw
also, compare-object says:

PS C:\WINDOWS\system32> 

我意识到我可以循环遍历并手动比较一组属性,如果我无法学习使用包含运算符的正确方法,我会这样做,但我正在尝试先这样做。

运算符文档似乎没有具体提到对象类型的元素。它确实使用了术语 "reference value",所以这是否暗示它必须是简单数据类型?但如果是这样,文档不应该提到这一点,也许 PS 会为无法比较的类型抛出某种软异常吗?

您正在将复杂对象与简单值进行比较。您需要比较等效的对象类型。作为向您展示的示例,将您的比较逻辑更改为:

($adusers_list | Select -Expand samaccountname) -contains $target_aduser.samaccountname

这实际上是将 AD 用户列表变成一个 string[],其中包含 $adusers_list 中用户的 samaccountname。然后我们比较等效值 ($target_user.samaccountname) 以查看 string 值是否包含在比较的 string[].