比较2个阵列与powershell

0g0grzrc  于 2023-02-12  发布在  Shell
关注(0)|答案(3)|浏览(138)

我有2个数组$UsersGroup和$UsersActive,我需要找到$UsersActive中包含SamAccountName和ObjectGUID的行的位置。
$用户组=

SamAccountName ObjectGUID
-------------- ----------
XXXX00XX       0031e949-9120-4df1-bddb-98067a141448
XXXX01XX       0031e949-9120-4df1-bdgb-99067a141448
XXXX02XX       0031e949-9120-4df1-bdab-97067a141448

并且没有标头
$活动用户=

fcb483fa146b
fcb515739a2f
fcb82f1ef74c
fcc5ee8b8722
fcd3f1f471c2
fceb26a598a3
fd0b14cecd0e
98067a141448

我需要将用户从$UsersActive匹配到$UserGroup.Object,就像这样

$UsersGroup | ForEach-Object {if($_.ObjectGUID -contains $UsersActive) {$_}}

但我没有得到这样的结果:


谁能帮帮我,谢谢!

ercv8c1e

ercv8c1e1#

-contains是一个 * 集合包含 * 运算符,用于测试右侧参数是否在左侧参数中准确出现。
要测试字符串中是否存在子字符串,请使用-like通配符字符串比较运算符:

$UsersGroup | Where-Object {
    $guid = $_.ObjectGUID
    $UsersActive.Where({$guid -like "*$_*"}, 'First')
}

现在,将针对每个$UsersActive值测试每个组条目,直到找到匹配项(使Where-Object传递对象)或找不到匹配项(使Where-Object过滤掉对象)

6rqinv9w

6rqinv9w2#

如果我没理解错的话,使用compare-object......它只有一个匹配项。对于大型列表,Compare-object可能会很慢。

$usersgroup = 
'SamAccountName,ObjectGUID
XXXX00XX,0031e949-9120-4df1-bddb-98067a141448
XXXX01XX,0031e949-9120-4df1-bdgb-99067a141448
XXXX02XX,0031e949-9120-4df1-bdab-97067a141448' | convertfrom-csv

$usersactive = -split
'fcb483fa146b
fcb515739a2f
fcb82f1ef74c
fcc5ee8b8722
fcd3f1f471c2
fceb26a598a3
fd0b14cecd0e
98067a141448'

compare ($usersgroup.objectguid -replace '.*-') $usersactive -IncludeEqual |
  ? sideindicator -eq '=='  # order doesn't matter

InputObject  SideIndicator
-----------  -------------
98067a141448 ==
pcww981p

pcww981p3#

提供替代解决方案:
如Mathias在his answer中所述,-contains运算符及其反向运算符-in只执行单个比较值与集合(数组)元素的 * 相等 * 比较。

  • 顺便说一句:假设$_.ObjectGUID是标量(单个对象),$UsersActive是要搜索的集合(数组),那么您需要使用-in,而不是-contains$_.ObjectGUID -in $UsersActive

不幸的是,从7.3.2版开始,PowerShell的 * 模式匹配 * 运算符-like(使用wildcard expressions)和-match(使用regexes)* 不 * 支持针对 * 多个 *(数组)模式进行匹配。
但是,由于您希望匹配每个.ObjectGUID值的一个 * literal substring *,因此如果您首先提取相关的子字符串并使用 * it * 作为比较值,则 * 可以 * 使用-in

# -> Object whose GUID is '0031e949-9120-4df1-bddb-98067a141448'
$usersGroup | Where-Object { ($_.ObjectGUID -split '-')[-1] -in $usersActive }

请注意-split operator是如何用于将GUID拆分为-标记的,[-1]返回 * last * 标记,然后-in通过相等比较在$UsersActive数组中查找该标记。
顺便说一句:

  • 允许 * 多个 * 模式作为-like-match的RHS--以便在它们中的 * 任何 * 匹配时返回$true--将是一个有益的未来改进。
  • GitHub issue #2132要求的就是这个。

相关问题