PowerShell pitfalls: reading text from file using get-content

I had a really strange effect in PowerShell that puzzled me for hours!

I have the following script:

$a = @'
One
Two
'@
$a
$p = [regex]"One"
$p.Replace($a, "OneReplaced")

$b = get-content -path templ.txt $b $q = [regex]"One" $q.Replace($b, "OneReplaced")

And a file templ.txt containing the following text:

One
Two

When I execute the script I get the following output:

One
Two
OneReplaced
Two
One
Two
OneReplaced Two

So what happens:

I initialize a variable $a with two lines of text: line 1: One, line 2: Two. When I display variable $a it shows One and Two on two seperate lines. I now replace One with OneReplaced. Output of the replacement is two lines of text. Line 1: OneReplaced, line 2: Two.

Everything ok so far.

I now read the contents of variable $b from the file templ.txt. This file contains two lines of text: line 1: One, line 2: Two. When I display variable $b it shows One and Two on two seperate lines. I now replace One with OneReplaced. Output of the replacement is ONE LINE of text: OneReplaced Two.

This is not what I expected.

After a lot of debugging I found out why this happened. When you do $b = get-content -path templ.txt you don't get a string back, but an object array. You can see that when you do: (get-content -path templ.txt).GetType(), this displays:

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Object[]                                 System.Array

If you inspect the Object[] variable $b, you see that $b[0] = "One" and $b[1] = "Two".

When the command $q.Replace($b, "OneReplaced") is executed, the variable $b of type Object[] is cast to a string. This cast combines the string objects in the Object[] by appending them with a space in the middle.

So what is the simple solution to all this: when reading the content, join all lines with a newline, as in the following code line:

$b = [string]::join([environment]::newline, (get-content -path templ.txt))

Such a pity that this costed me 4 hours, I thought it was in the regular expression replacement:-(

But the good thing is that I can now solve that nasty bug in my Template Engine using PowerShell expressions.

29 Comments

Comments have been disabled for this content.