2

How can I force string variable expansion?

I need to read a string with one or more variable names in it (a template) and then expand it after I read the file. The key is that I must read the contents of the file before I declare the variables that will be used in the expansion. I've tried several ways but I can't get it to work.

It's not an option to read the file after $environment is defined.

Contents of name.txt: $environment-RPT-INT

#example 1
$name = gc "c:\temp\name.txt"
$environment = "9065DEV" 
$expanded = $ExecutionContext.InvokeCommand.ExpandString($name)
$expanded

#example 2
$name = gc "c:\temp\name.txt"
$environment = "9065DEV" 
$expanded = $expanded = Invoke-Expression "`"$template`""
$expanded

#example 3
$name = gc "c:\temp\name.txt"
$environment = "9065DEV"
$name = $name.Clone()
$expanded = $ExecutionContext.InvokeCommand.ExpandString($name)
$expanded

Any help is appreciated.

Updated: Example 1 is now working for me.

4
  • Hello there! Are you saying $name contains the name of a variable that you want to get? If so, you can use Get-Variable -Name $Name -ValueOnly. If not, mind clarifying your desired goal with a little pseudo code? Commented Apr 11, 2014 at 20:49
  • I'm using Powershell v2 and your first example works for me, what version are you using and what is your output? Commented Apr 11, 2014 at 20:53
  • $name contains the contents of the file c:\temp\name.txt, which I specify is the string: $environment-RPT-INT Commented Apr 11, 2014 at 20:54
  • I'm using Powershell 4.0. Commented Apr 11, 2014 at 20:54

4 Answers 4

4

It looks like you've found some possible solutions, but I'll suggest another that is in my opinion a bit smarter and more robust.

Instead of requiring variable names in your text file, why not use format specifiers. For example, the contents of name.txt:

{0}-RPT-INT

And in your script:

$name = gc "c:\temp\name.txt"
$environment = "9065DEV" 
$expanded = $name -f $environment
$expanded

This way, you can rename the variable w/o changing any of your text files. As a bonus, if your text file comes from unknown sources, your script is vulnerable to code injection. For example, say you are given a text file with these contents:

$(rm -whatif -recurse -force c:\)-RPT-INT

Then ExpandString or Invoke-Expression will happily execute that code.

Sign up to request clarification or add additional context in comments.

Comments

2

Your Invoke-Expression example is pretty close. Instead of using $template though, you need to use $name.

#example 2
$name = gc 'c:\temp\name.txt';
$environment = '9065DEV';
$expanded = Invoke-Expression -Command "`"$name`"";
$expanded;

Comments

1

There is a function called ExpandString predefined in powershell. It's inside $ExecutionContext, as follows.

$mystring = @'
This is a here string with some embedded variables.

Here is variable foo -- $foo
Here is variable bar -- $bar
Here is variable bletch -- $bletch

'@

#This displays the here string as is.

$mystring

#now define foo, bar and bletch

$foo = 5
$bar = Get-Date
$bletch = "George Washington"

#now run the here string through Expandstring.

$ExecutionContext.InvokeCommand.ExpandString($mystring)

Comments

0

If you are willing to store your Setting/Values in a CSV, I wrote a module to pull values from a CSV, put it into a HereString... any variables you put into the CSV become fully expanded inside the Here-String. That way, you can normally address the field names and values.

I might be able to change this to also work with traditional INI's if anyone is interested.

https://github.com/Inventologist?tab=repositories

Look for: HereStringFromCSV

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.