0phoi5 Posted February 3, 2017 Posted February 3, 2017 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. Quote
0phoi5 Posted February 6, 2017 Author Posted February 6, 2017 On 03/02/2017 at 4:56 PM, digip said: Try "`@*" maybe? Thanks. Still no luck This still returns all as a positive match ('Yep'), when the last 2 should return negative. Weird! Quote
IDNeon Posted March 3, 2017 Posted March 3, 2017 (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 March 3, 2017 by IDNeon Quote
0phoi5 Posted March 6, 2017 Author Posted March 6, 2017 (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 March 6, 2017 by haze1434 Quote
0phoi5 Posted March 6, 2017 Author Posted March 6, 2017 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. Quote
Jason Cooper Posted March 6, 2017 Posted March 6, 2017 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", "asd@test3"); foreach ($group in $x) { if ("$group" -match "`@") { echo "yep $group" } else { echo "Nope $group" } } results in yep @test Nope test2 yep asd@test3 while $x = @("@test", "test2", "asd@test3"); foreach ($group in $x) { if ("$group" -match "^@") { echo "yep $group" } else { echo "Nope $group" } } results in yep @test Nope test2 Nope asd@test3 Quote
0phoi5 Posted March 6, 2017 Author Posted March 6, 2017 (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 @{Name=@Testone} yep @{Name=@Testtwo} yep @{Name=Testthree} yep @{Name=Testfour} Edited March 6, 2017 by haze1434 Quote
0phoi5 Posted March 6, 2017 Author Posted March 6, 2017 (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 March 6, 2017 by haze1434 Quote
Jason Cooper Posted March 6, 2017 Posted March 6, 2017 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. "@{Name=@Testone}". 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" } } Quote
IDNeon Posted March 6, 2017 Posted March 6, 2017 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. Quote
IDNeon Posted March 6, 2017 Posted March 6, 2017 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. "@{Name=@Testone}". 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? Quote
Jason Cooper Posted March 6, 2017 Posted March 6, 2017 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 @{Name=@Testone} @{Name=@Testtwo} @{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. Test@five) as it will be matched by the "`@[a-zA-Z0-0]" regular expression as well. Quote
IDNeon Posted March 6, 2017 Posted March 6, 2017 (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 @{Name=@Testone} @{Name=@Testtwo} @{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. Test@five) 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 March 6, 2017 by IDNeon Quote
0phoi5 Posted March 7, 2017 Author Posted March 7, 2017 Thanks all :) I get what happened now. Quite ironic that the stringified $group variable began with an @ symbol ! Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.