I have 2 Arrays $UsersGroup and $UsersActive, i need to find where in $UsersActive i have a line with SamAccountName and the ObjectGUID .
$UsersGroup =
SamAccountName ObjectGUID
-------------- ----------
XXXX00XX 0031e949-9120-4df1-bddb-98067a141448
XXXX01XX 0031e949-9120-4df1-bdgb-99067a141448
XXXX02XX 0031e949-9120-4df1-bdab-97067a141448
and without headers
$UsersActive =
fcb483fa146b
fcb515739a2f
fcb82f1ef74c
fcc5ee8b8722
fcd3f1f471c2
fceb26a598a3
fd0b14cecd0e
98067a141448
I need to have the match user from $UsersActive to $UserGroup.Object like that
$UsersGroup | ForEach-Object {if($_.ObjectGUID -contains $UsersActive) {$_}}
But i don't get the result like that :
XXXX00XX 0031e949-9120-4df1-bddb-98067a141448
Can some one help me , thanks !
CodePudding user response:
-contains
is a collection containment operator, testing for the exact occurrence of the right-hand side argument in the left-hand side argument.
To test for the presence of a substring in a string, use the -like
wildcard string comparison operator:
$UsersGroup | Where-Object {
$guid = $_.ObjectGUID
$UsersActive.Where({$guid -like "*$_*"}, 'First')
}
Each group entry will now be tested against every $UsersActive
value until a match is found (causing Where-Object
to pass the object through) or no match is found (causing Where-Object
to filter out the object)
CodePudding user response:
To offer an alternative solution:
As Mathias states in his answer, the -contains
operator and its operands-reversed counterpart, -in
, only perform equality comparison of a single comparison value against the elements of a collection (array).
- As an aside: Given that
$_.ObjectGUID
is the scalar (single object) and$UsersActive
the collection (array) to search in, you would have needed to use-in
, not-contains
($_.ObjectGUID -in $UsersActive
)
Unfortunately, as of version 7.2.x PowerShell's pattern-matching operators, -like
(with wildcard expressions) and -match
(with regexes), do not support matching against multiple (an array of) patterns.
However, since you're looking to match a literal substring of each .ObjectGUID
value, you can use -in
if you extract that relevant substring first and use it as the comparison value:
# -> Object whose GUID is '0031e949-9120-4df1-bddb-98067a141448'
$usersGroup | Where-Object { ($_.ObjectGUID -split '-')[-1] -in $usersActive }
Note how the -split
operator is used to split the GUID into tokens by -
, with [-1]
returning the last token, which -in
then looks for by equality comparison in the $UsersActive
array.
As an aside:
Allowing multiple patterns as the RHS of
-like
and-match
- so as to return$true
if any of them match - would be a helpful future improvement.GitHub issue #2132 asks for just that.
CodePudding user response:
If I understand you correctly, using compare-object... This has only one match. Compare-object can be slow for large lists.
$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 ==