如何比较含数组的两个PowerShell对象并返回匹配的完整对象
问题描述
我有两个包含IP地址的PowerShell对象,需要对它们进行比较:如果obj1中的某个对象的IP地址列表与obj2的IP地址列表有至少一个重叠,就返回obj1中该对象的完整信息(包含Owner字段)。目前只能实现匹配并输出IP地址,但尝试获取完整对象的代码无法生效,期望返回包含192.168.1.1的PC1完整对象。
示例代码
$obj1 = @() $obj1+= [pscustomobject]@{'Name' = 'PC1'; 'IPAddress' = @('192.168.2.2','192.168.1.1'); 'Owner' = 'user1'} $obj1+= [pscustomobject]@{'Name' = 'PC2'; 'IPAddress' = @('192.168.8.7','192.168.5.5'); 'Owner' = 'user2'} $obj1+= [pscustomobject]@{'Name' = 'PC3'; 'IPAddress' = @('192.168.6.2','192.168.19.19'); 'Owner' = 'user3'} $obj2 = [pscustomobject]@{'Name' = 'PC1'; 'IPAddress' = @('192.168.1.1','192.168.3.4','10.12.55.11')}
当前可用的IP匹配代码
$obj1.IPAddress | where {$obj2.IPAddress -contains $_}
无效的完整对象匹配尝试
$obj1 | where {$obj2.IPAddress -contains $_.IPAddress}
解决方案
原因分析
无效代码的问题在于:$_.IPAddress是一个数组,而-contains运算符仅用于检查单个值是否存在于目标数组中,无法直接用数组与数组做匹配,因此得不到预期结果。
正确实现方式
方式1:遍历IP列表逐一匹配
$obj1 | Where-Object { # 遍历当前对象的每个IP,检查是否在obj2的IP列表中 foreach ($ip in $_.IPAddress) { if ($obj2.IPAddress -contains $ip) { return $true } } return $false }
方式2:利用集合交集判断
通过哈希集合的交集方法,更高效地判断两个IP列表是否有重叠:
# 将obj2的IP转为哈希集合,提升匹配效率 $obj2IPSet = [System.Collections.Generic.HashSet[string]]$obj2.IPAddress $obj1 | Where-Object { $currentIPSet = [System.Collections.Generic.HashSet[string]]$_.IPAddress # 计算两个集合的交集 $currentIPSet.IntersectWith($obj2IPSet) # 若交集数量大于0,说明存在匹配IP $currentIPSet.Count -gt 0 }
运行结果
执行上述代码后,会返回PC1的完整对象:
Name IPAddress Owner ---- --------- ----- PC1 {192.168.2.2, 192.168.1.1} user1
内容的提问来源于stack exchange,提问作者Oleg0341
相关产品推荐
相关产品推荐

