1

I have found something unusual with PowerShell strings...I hope this is just something I'm missing. Here's what I found.

I copied some data from a web page (KQL searches for O365 if anyone cares), and it contained hidden control characters. Here are the two lines as I stored them in PowerShell variables:

PS C:\Users> $L1 = "(c:c)(date=01/01/2014..11/01/2016)"
PS C:\Users> $L2 = "(c:c)‎‎(date=01/01/2014..11/01/2016)‎"

The second line has two hidden characters (Unicode character 8206) between the "(c:c)" and the "(date". I believe they are still there in this post. Because of this, the two strings have different lengths:

PS C:\Users> $L1.Length
34

PS C:\Users> $L2.Length
36

And yet, when I check to see if they are equal to each other, PowerShell tells me they are:

PS C:\Users> $L1 -eq $L2
True

Now, I know it understands that there are differences there. I can use the substring method to pull out some characters, and show that the substrings are not equal:

PS C:\Users> $L1.Substring(4,8)
)(date=0

PS C:\Users> $L2.Substring(4,8)
)‎‎(date

If I use the -eq operator to compare those substrings, I get the correct answer:

PS C:\Users> $L1.Substring(4,8) -eq $L2.Substring(4,8)
False

But if I force the strings to display the same by changing how many characters I grab so I get the same 6 visible characters, then PowerShell will tell me that they are equal:

PS C:\Users> $L1.Substring(4,6)
)(date

PS C:\Users> $L2.Substring(4,8)
)‎‎(date

PS C:\Users> $L1.Substring(4,6) -eq $L2.Substring(4,8)
True

So, is this expected behavior? Am I missing something? I've been programming long enough that I know string handling can be weird...but this is beyond my personal experience.

If it is expected behavior, how to I properly compare two string variables to see if they are exactly the same?

Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
Matthew
  • 1,096
  • 7
  • 12
  • 1
    `[String]::Equals($L1, $L2, 'Ordinal')` – user4003407 Aug 23 '17 at 17:25
  • [`[String]::Equals($L1, $L2, "Ordinal")`](https://msdn.microsoft.com/library/t4411bks). Try `"CurrentCulture"` or `"InvariantCulture"` instead to see a culture-sensitive comparison. – Jeroen Mostert Aug 23 '17 at 17:25
  • Appreciate the working answer, however it leaves me with the question of why the $L1 -eq $L2 is returning true. Is that because it is doing something similar to the "CurrentCulture" or "InvariantCulture" comparisons? How can I function if I can't trust something as simple as $L1 -eq $L2 will return a ... simple ... answer? :) – Matthew Aug 23 '17 at 17:59
  • Apparently `$L2` contains 3 "left-to-right-mark" characters (U+200e) which seem to be ignored in the comparison. This probably has to do with what Jon Skeet ranted abou^W^Wdiscussed in his legendary ["OMG Ponies!!!" talk](https://blogs.msmvps.com/jonskeet/2009/11/02/omg-ponies-aka-humanity-epic-fail/) on the 2009 DevDays. – Ansgar Wiechers Aug 23 '17 at 20:41

0 Answers0