PowerShell quickie: expanding the properties of a variable inside a string

Here’s something that gave me a bit of trouble: I was attempting to run a script to upgrade a bunch of SharePoint solutions, and I wrote it like this:

dir –Recurse –Filter *.wsp | %{ stsadm –o upgradesolution –name $_ –filename $_.FullName –allowgacdeployment –local }

Now, that actually works, but since I hadn’t tested it before, I figured I’d echo the command out first, so I tried this:

dir –Recurse –Filter *.wsp | %{ echo "stsadm –o upgradesolution –name $_ –filename $_.FullName –allowgacdeployment –local" }

Which is all well and good, except it echos out something like the following:

stsadm –o upgradesolution -name Foo.wsp -filename Foo.wsp.FullName -allowgacdeployment -local

The reason this happens is that the string expansion in PowerShell has no way of knowing that I meant to expand the property instead of printing out the literal characters. Having figured this out, the next thing I tried was:

echo "${_.FullPath}"

Which doesn’t work either. Crap. I’m not familiar enough with the PowerShell syntax to explain why that is, but after a moment of pondering I finally figured out something that does work – expressions:

dir –Recurse –Filter *.wsp | %{ echo "stsadm –o upgradesolution –name $_ –filename $($_.FullName) –allowgacdeployment –local" }

The $() syntax allows us to evaluate any arbitrary expression, which is then inserted into the string. Yay!

2 comments

  • Yes. Also, there is no fundamental reason why you couldn’t just use string catenation if that’s more familiar to you; “foobar” + $_.FullName + “baz” works fine.

    Of course, you can also leave “echo” out; just having a string as a statement will cause it to be thrown down the pipe (and eventually passed into Out-Host, printing them onscreen).

  • Of course, and that’s what I did at first. However, inquiring minds want to know, and all that. 🙂

    That said, it did occur to me why the curly brace syntax wouldn’t work. It’s usable for two scenarios: namespaced variables (such as ${env:foo}) and to explicitly denote that a variable name ends at a particular point (such as “${foo}bar”, where “$foobar” would mean a different thing). What I was trying to expand was, in fact, an expression and not just a variable. 🙂

Leave a Reply

Your email address will not be published. Required fields are marked *