5

So the easiest way to explain my problem is for me to show you this simplified version of what I'm trying to do:

PS C:\> $a = 'hello'
PS C:\> $a
hello
PS C:\> $b = '$a world!'
PS C:\> $b
$a world!

Now what I really want is for the invokation of $b to return 'hello world!' but I apparently cannot call a variable within anther variable like this. Does anyone have any suggestions or work-arounds? I feel like I'm just missing something obvious here.

Edit: a more accurate version of what I'm trying to do:

PS C:\> $selHost = (get-content c:\scripts\hosts.txt)[0]
PS C:\> $selhost
spr-it-minion
PS C:\> $a = (get-content c:\scripts\config.txt)[1]
PS C:\> $a
$selhost Is Offline!
PS C:\> $b = "$a"
PS C:\> $b
$selhost Is Offline!

So I'm pulling the first line out of hosts.txt and setting it to $selhost which is just 'spr-it-minion'. I then pull the second line out of config.txt which is just the string '$selhost is offline!' in hopes that when I call $a I get 'spr-it-minion is offline!' and I'm not sure what to do.

Edit II: the contents of hosts.txt and config.txt respectively.

hosts.txt:

spr-it-minion
spr-saflok
spr-crosby
spr-vmhost01
spr-vmhost02
spr-vmhost03

config.txt:

172.31.1.124
$selhost Is Offline!
$selhost Is Offline!
example@company.com
example2@company.com

Edit III: The Pastebin to my actual script if any of you are interested.

Line 15: I set $alertSubject to the string "$selhost is offline!" with no quotes or anything.

Line 82: I use $alertSubject as the subject line of an email alert hoping that that variable it contains will have it's value represented like: "spr-it-minion is offline!" but when I get the email or try to write-host $alertSubject anywhere in the script it just says "$selhost is offline!"

  • Please edit again to show us the actualy line [0] from the hosts.txt and line [1] from the config.txt. It'll help.. ;) – Ƭᴇcʜιᴇ007 May 1 '15 at 19:29
  • While I do not know for sure, seeing as I'm not a PowerShell user, I am suspecting that you don't need to use quotes at all when assigning a variable to another variable. $a = $b should work too. Think of " as meaning "unpack what's here, including any variables". Can someone confirm that this is the case? – Jarmund May 1 '15 at 19:32
  • Edited to include the contents of hosts.txt and config.txt. – Catatonic27 May 1 '15 at 19:32
  • Edited to include the pastebin link to the actual script and the areas that are causing this issue. – Catatonic27 May 1 '15 at 19:44
8

When defining variables in PowerShell, single quotes (') mean you want the literal version of the string. Use double-quotes (") if you want to allow variable expansion:

PS C:\> $a = "hello"
PS C:\> $a
hello
PS C:\> $b = "$a world!"
PS C:\> $b
hello world!

More info:

Edit after comments:

For your example where you're pulling the line from a file, that's a little trickier since it's pulling the line as a literal string.

The easiest way (IMO) would be to use the Replace method; something like:

$selHost = (get-content c:\scripts\hosts.txt)[0]
$a = ((get-content c:\scripts\config.txt)[1]).replace('$selhost', $selHost)
  • 1
    A noteworthy point is that this behavior of single- vs double-quotes isn't just PowerShell, but any language with sensible string-operations that I know of. – Jarmund May 1 '15 at 19:14
  • @Jarmund Most "sensible" languages I've run into over the years don't allow mixing at all. Double quotes are for Strings, and single quotes are for Chars. In the end that doesn't really matter though, because this question is PowerShell specific. ;) – Ƭᴇcʜιᴇ007 May 1 '15 at 19:17
  • @Techie007 True, this is somewhat redundant at this point, so I'll just leave this statement and walk away: A sensible language doesn't necessarily have sensible string operations. :P – Jarmund May 1 '15 at 19:20
  • @Jarmund True enough, and any language can be considered "sensible" or not, depending on who's using it and for what. ;) – Ƭᴇcʜιᴇ007 May 1 '15 at 19:23
  • Thanks! I'm pretty new to programming in general and I got the impression that ' and " were pretty interchangeable. Unfortunately, I might have simplified my example too much. Look at this example: PS C:\> $selHost = (get-content c:\scripts\hosts.txt)[0] PS C:\> $selhost spr-it-minion PS C:\> $a = (get-content c:\scripts\config.txt)[1] PS C:\> $a $selhost Is Offline! So I'm pulling a line out of hosts.txt and setting it to $selhost. I then pull a line out of config.txt which is just '$selhost is offline!' in hopes that when I call $a I get 'spr-it-minion is offline!' and nothing. – Catatonic27 May 1 '15 at 19:24
0

Use $(

Example: $Var1 = $(Var2 | Select-Object -Property A)

$Var1 will equal the A property of Var2. Pretty robust.

0

When you read a string that contains a variable name out of a file and into a variable, you are going to need something other than double quotes to cause string expansion. There is a tool that's relevant here. It's called ExpandString. Take a look at this sample code:

$selhost = 'spr-it-minion'

$b = '$selhost is offline!'
$c = $ExecutionContext.InvokeCommand.ExpandString($b)

$c

What's going on here is that first I have given $selhost and $b literal values, similar to the ones you would read out of the files you are using. Of course, $b isn't right, because the reference to $selhost isn't resolved, as outlined in the accepted answer. But $c gets the value produced by expanding $selhost, which you can use in your output.

I'll leave applying this to your case as a coding exercise.

0

The replace method works well for variable within variable substutition, even when calling powershell from Autohotkey:

uri = file$k.doc

psScript2 =
(
param($param1)
for($k=1; $k -le 6; $k++){
$uri = $param1.replace('$k',"$k")
echo $uri
}
)

Run PowerShell.exe -noexit -Command &{%psScript2%} '%uri%',, show
return

Note the use of single quotes to search for inner variable to be substituted with outer variable contents

Result is:

file1.doc
file2.doc
etc.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.