Jump to content
Hak5 Forums
Sign in to follow this  
haze1434

Powershell - match, like, contains not working with @ symbol

Recommended Posts

Hi guys,

I have the following PowerShell script, which finds the list of groups a user is a member of, formats them to name only, and then is supposed to list yes or no to which groups begin with the '@' symbol;

$CurrentGroups = Get-ADuser JOEBLOGGS -property MemberOf | % {$_.MemberOf | Get-ADGroup | select Name | sort name}

foreach($Group in $CurrentGroups) {
if("$Group" -match "`@") { echo Yep $Group }
else { echo Nope $Group }}

 

User JOEBLOGGS is a member of;

  • @Testone
  • @Testtwo
  • Testthree
  • Testfour

 

On running this script, I would expect the output to be;

Yep
@Testone
Yep
@Testtwo
Nope
Testthree
Nope
Testfour

However, it instead states 'Yep' to all of them, not just the groups beginning with an '@' symbol.

 

I have tried -like, -match, -contains as well as "\@", "@*" and "@". None work correctly.

 

If I run -match "@Test", this works fine, but not all of the groups in our AD that begin with an @ symbol follow with the same digits, so I need this to work with just searching for all groups that begin with an @ symbol.

Thank you.

Share this post


Link to post
Share on other sites

Try "`@*" maybe?

Share this post


Link to post
Share on other sites
On ‎03‎/‎02‎/‎2017 at 4:56 PM, digip said:

Try "`@*" maybe?

Thanks. Still no luck :sad: This still returns all as a positive match ('Yep'), when the last 2 should return negative.

Weird!

Share this post


Link to post
Share on other sites
Posted (edited)
On 2/6/2017 at 1:44 AM, haze1434 said:

Ah!

`@[A-Za-z0-9] 

Success!!

Ok, but can you answer WHY it failed when it was just "`@"?

Because WHY it failed is more important than how to make it work.

I don't know how often you code, but sometimes it's good to build your own debuggers into code:

Thought about it for a moment and the why is the match is you are NOT matching $Group but matching $CurrentGroups.

I haven't thought of a way to test this yet, but it's the only logical way I can think of why your first code failed.

Edited by IDNeon

Share this post


Link to post
Share on other sites
Posted (edited)
On ‎03‎/‎03‎/‎2017 at 10:40 PM, IDNeon said:

Because WHY it failed is more important than how to make it work.

Not always. We don't understand why Quantum Mechanics works, but we're making Quantum Computers anyway.

I agree that it's important to find out why something works, yes, but not the most important thing. Sometimes deadlines and requirements come first, stuff like that comes after. No ideal, agreed, but that's life.

Edited by haze1434

Share this post


Link to post
Share on other sites
On ‎03‎/‎03‎/‎2017 at 10:40 PM, IDNeon said:

Thought about it for a moment and the why is the match is you are NOT matching $Group but matching $CurrentGroups.

Not sure what you mean, sorry.

$Group is a variable already recognised by PowerShell - The line 'foreach($Group in $CurrentGroups)' works fine.

Share this post


Link to post
Share on other sites

Doesn't -match take a regular expression? If so have you tried "^@" to match a string starting with the @ symbol?

What's really interesting though is that you got it returning true for all your groups whether they contained an @ symbol or not, which is something I haven't been able to recreate. e.g.

$x = @("@test", "test2", "[email protected]");

foreach ($group in $x) {
  if ("$group" -match "`@") {
    echo "yep $group"
  } else {
    echo "Nope $group"
  }
}

results in

yep @test
Nope test2
yep [email protected]

while

$x = @("@test", "test2", "[email protected]");

foreach ($group in $x) {
  if ("$group" -match "^@") {
    echo "yep $group"
  } else {
    echo "Nope $group"
  }
}

results in 

yep @test
Nope test2
Nope [email protected]

 

Share this post


Link to post
Share on other sites
Posted (edited)

$y = Get-ADuser JOEBLOGGS -property MemberOf | % {$_.MemberOf | Get-ADGroup | select Name | sort name}

foreach ($group in $y) {

if ("$group" -match "^@") {

echo "yep $group"

} else {

echo "Nope $group"

}

}

yep @{[email protected]}

yep @{[email protected]}

yep @{Name=Testthree}

yep @{Name=Testfour}

Edited by haze1434

Share this post


Link to post
Share on other sites
Posted (edited)

No luck, as above. Must be something to do with the way it's parsing Get-ADuser? (rather than setting the variables without Get-ADuser)

I assume I'm doing something wrong here: $y = Get-ADuser JOEBLOGGS -property MemberOf | % {$_.MemberOf | Get-ADGroup | select Name | sort name}

Edited by haze1434

Share this post


Link to post
Share on other sites

Seeing your output suddenly makes it all make sense. The $group variable isn't a simple string, it's actually an object with a Name property. When you put it in double quotes Powershell produces a stringified version of the object, which starts with the @ symbol (e.g. "@{[email protected]}". You then do a regular expression match against that string, which sees the first character as the @ symbol, which is matches what it's looking for exactly.

I don't have access to an active directory to test, but try matching against the $group object's Name propery instead, e.g.

$y = Get-ADuser JOEBLOGGS -property MemberOf | % {$_.MemberOf | Get-ADGroup | select Name | sort name}

foreach ($group in $y) {
    if ($group.Name -match "^@") {
        echo "yep $group"

    } else {
        echo "Nope $group"
    }
}

 

  • Upvote 1

Share this post


Link to post
Share on other sites
3 hours ago, haze1434 said:

Not sure what you mean, sorry.

$Group is a variable already recognised by PowerShell - The line 'foreach($Group in $CurrentGroups)' works fine.

I was in the middle of a thought process (and editing my previous posts to update) but got busy, usually that happens and you'll just have to move on from those posts when I don't get back to them.

What I was trying to show before I had to abandon it was what the value of $Group actually was when -match compares it to your expression.

I wanted to see if the $Group value was carrying the @ through its comparison.

I was in the process of writing a little debugger for that but got busy and this is the first time in 3 days I have had time to revisit this thread.

Share this post


Link to post
Share on other sites
21 minutes ago, Jason Cooper said:

Seeing your output suddenly makes it all make sense. The $group variable isn't a simple string, it's actually an object with a Name property. When you put it in double quotes Powershell produces a stringified version of the object, which starts with the @ symbol (e.g. "@{[email protected]}". You then do a regular expression match against that string, which sees the first character as the @ symbol, which is matches what it's looking for exactly.

I don't have access to an active directory to test, but try matching against the $group object's Name propery instead, e.g.

$y = Get-ADuser JOEBLOGGS -property MemberOf | % {$_.MemberOf | Get-ADGroup | select Name | sort name}

foreach ($group in $y) {
    if ($group.Name -match "^@") {
        echo "yep $group"

    } else {
        echo "Nope $group"
    }
}

 

Not sure that's the answer though EITHER?


Because the OP provided a solution "`@[a-zA-Z0-9]" which has an intended result

This means your explanation does not explain why his solution would work to segregate as it did?

Share this post


Link to post
Share on other sites
17 minutes ago, IDNeon said:

Not sure that's the answer though EITHER?


Because the OP provided a solution "`@[a-zA-Z0-9]" which has an intended result

This means your explanation does not explain why his solution would work to segregate as it did?

Actually it does explain why it worked, but I'll go into it in a bit more depth.

When using the $Group in double quotes it stringifys the value of the object so we have four strings

@{[email protected]}
@{[email protected]}
@{Name=Testthree}
@{Name=Testfour}

The regular expression the OP provided as a solution is looking for an @ symbol followed by a character that is in the range or a - z, A - Z or 0 - 9. While all four strings start with an @ symbol those are immediately followed by an open brace '{' which doesn't match the pattern that the regular expression is looking for. The first and second strings have another @ symbol which does match the pattern as they're followed by the letter 'T' which is in the range being matched.

The OP's solution however doesn't actually meet the criteria of only matching groups starting with an @ symbol as any groups that contain an @ symbol in the middle of their name (e.g. [email protected]) as it will be matched by the "`@[a-zA-Z0-0]" regular expression as well.

Share this post


Link to post
Share on other sites
Posted (edited)
20 minutes ago, Jason Cooper said:

Actually it does explain why it worked, but I'll go into it in a bit more depth.

When using the $Group in double quotes it stringifys the value of the object so we have four strings

@{[email protected]}
@{[email protected]}
@{Name=Testthree}
@{Name=Testfour}

The regular expression the OP provided as a solution is looking for an @ symbol followed by a character that is in the range or a - z, A - Z or 0 - 9. While all four strings start with an @ symbol those are immediately followed by an open brace '{' which doesn't match the pattern that the regular expression is looking for. The first and second strings have another @ symbol which does match the pattern as they're followed by the letter 'T' which is in the range being matched.

The OP's solution however doesn't actually meet the criteria of only matching groups starting with an @ symbol as any groups that contain an @ symbol in the middle of their name (e.g. [email protected]) as it will be matched by the "`@[a-zA-Z0-0]" regular expression as well.

Brilliant thanks for that clarification.

That's why I wanted to get deeper into this, my gut feeling was that the big-picture wasn't well understood and as you said, the "solution" was really not a solution.

Reason I wanted to pursue that was it's in those patch-jobs that problems are created.  Your explanation would provide for a completely exact answer.

Edited by IDNeon

Share this post


Link to post
Share on other sites

Thanks all :) I get what happened now.

Quite ironic that the stringified $group variable began with an @ symbol !

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.

×