views:

259

answers:

1

I am trying to implement macro replacement based on this discussion. Basically it works, but seems the ExpandString have some limitatoins:

main.ps1:

$foo = 'foo'
$text = [IO.File]::ReadAllText('in.config')
$ExecutionContext.InvokeCommand.ExpandString($text) | out-file 'out.config'

in.config (OK):

$foo

in.config (Error: "Encountered end of line while processing a string token."):

"

in.config (Error: "Missing ' at end of string."):

'

The documentation states:

Return Value: The expanded string with all the variable and expression substitutions done.

What is 'expression substitution' (may be this is my case)?

Is there some workaround?

+2  A: 

The error is occurring because quotes (single and double) are special characters to the PowerShell runtime. They indicate a string and if they are to be used as just that character, they need to be escaped.

A possible workaround would be to escape quotes with a backtick, depending on your desired result.

For example if my text file had

'$foo'

The resulting expansion of that string would be

PS>$text = [io.file]::ReadAllText('test.config')
PS>$ExecutionContext.InvokeCommand.ExpandString($text)
$foo

If you wanted to have that variable expanded, you would need to escape those quotes.

`'$foo`'
PS>$text = [io.file]::ReadAllText('test.config')
PS>$ExecutionContext.InvokeCommand.ExpandString($text)
'foo'

or if you were going to have an unpaired single or double quote, you would need to escape it.

You could do a -replace on the string to escape those characters, but you'll have to make sure that is the desired effect across the board.

PS>$single, $double = "'", '"'    
PS>$text = [io.file]::ReadAllText('test.config') -replace "($single|$double)", '`$1'
PS>$ExecutionContext.InvokeCommand.ExpandString($text)

NOTE: After you do the ExpandString call, you won't have the backticks hanging around anymore.

Steven Murawski