TIL PowerShell .replace != -replace

While Linux maintains a strict case-sensitivity that you grow used to dealing with over time, Windows users get a little complacent, and often expect things to “just work.” I ran into a problem this week with an XML config file that I expected certain nodes to have string values that I could replace for various situations, and it came down to an unusual little conflict between the underlying .Net and the PowerShell API that you’ve come to know, specifically something like:

[string]$myString = "LittleBlueHen".replace ("hen","sheep") 

Some colleagues at StackOverflow helped tickle my brain cells into remembering that PowerShell’s inline methods do not always equate to the .Net equivalents, although I’ve seen it commingled in various places. The difference between .Net’s string.replace() method and Powershell’s regex -replace operator is explained more deeply here, although it fails to go into the nuances of regex patterns, nor case-sensitivity, and thus this particular stumble caused more than a few minutes of head-banging. In fact, there’s a lingering echo of doubt because I could swear that (maybe in earlier PowerShell), this used to “just work”

Digging into this deeper, I was educated on more case-insensitive default behavior, as other PowerShell regex-based operations such as -match or -pattern are similar (if you’re using strings, but not if you’re using regex objects so you have to be careful as it’s not mentioned in some places like this which imply a performance difference)

@("What","Why") | Select-String -pattern "wh"

And so I leave you with this to decipher :

invoke-expression '"LittleBlueHen".replace("hen","sheep")'.replace(".replace"," -replace")

Authors