11
Get-WmiObject -Class win32_logicaldisk -Filter 'DeviceID="C:"'

does what I want,

$var="C:"
Get-WmiObject -Class win32_logicaldisk -Filter 'DeviceID="{$var}"'

does nothing. I tried to change the quotes, to concatenate strings, and other 1000 things, but they didn't work. Why the above example doesn't work, and what would work?

6
  • 1
    -Filter "DeviceID='$var'" (notice the double-quotes around the filter string) Commented Dec 1, 2016 at 16:16
  • @MathiasR.Jessen as mentioned, I tried to reverse the quotes, it doesn't work Commented Dec 1, 2016 at 16:20
  • 1
    Did you actually try it? In your example you've put {} around the variable, which will surely make the query return nothing Commented Dec 1, 2016 at 16:22
  • didn't notice the {}. Now it works. I can't believe this did not happen to be one of the 1000 things I've tried, because for sure I tried 'DeviceID="$var"', and I thought that ' 'and " " are the same, but each one goes inside the other. Still, do you know why the {} didn't work? I used {$var} inside strings a lot of times, and just now it didn't work. Also, you can add your solution as an answer. Commented Dec 1, 2016 at 16:26
  • 1
    ${var} would have worked, and resulted in the string C:, but {$var} would result in the string {C:} Commented Dec 1, 2016 at 16:30

3 Answers 3

14

When you start a string literal with ' (single-quotes), you're creating a verbatim string - that is, every character inside the string is interpreted literally and variable references and expressions won't expand!

Use " if you want the variable to be expanded:

$var = 'C:'
Get-WmiObject -Class win32_logicaldisk -Filter "DeviceID='$var'"

If your variable name has weird characters, or is followed by a word character, you can qualify the variable name with curly brackets {} immediately after the $:

$var = 'C:'
Get-WmiObject -Class win32_logicaldisk -Filter "DeviceID='${var}'"
Sign up to request clarification or add additional context in comments.

Comments

6

If, for instance, you're getting data from a file with select-string, the return is a single quote string. If that string contains variables they won't expand. Invoke-Expression can be used if the variable is clean - not mixed in with other text:

$abc = 123
$a = '$abc'
iex $a -> 123

If the variable is part of a path name, this doesn't work. Use $ExecutionContext.InvokeCommand.ExpandString($var)

$path = '$Home/HiMum'
$ExecutionContext.InvokeCommand.ExpandString($path)
-> /home/JoeBlogs/HiMum

You lucky sods on Windows might be able to use Convert-String to change singles to doubles.

Comments

3

I didn't find expanding expressions in PowerShell, but here's what I found.

# Let's set some varaible
$ComputerName = 'some-value'

# Let's store this variable name
$name = 'ComputerName'

# Get value by `Get-Item`.
(Get-Item variable:$name).Value # throws an exception for undefined variables.

# Get value by `Invoke-Expression`
Invoke-Expression "`$variable:$name"
Invoke-Expression "`$$name"

The same but for environment variables

(Get-Item env:$name).Value # throws an exception for undefined environments.
Invoke-Expression "`$env:$name"

I prefer Get-Item as it "fails loudly".

And Get-Item allows to use additional literals during this process, as well as Invoke-Expression.
I.e. see the Computer literal below before the $ sign.

$otherName = 'Name'

(Get-Item variable:Computer$otherName).Value
(Get-Item env:Computer$otherName).Value

1 Comment

to use in command arguments do it like this "$env:temp\*.tmp" | ls -filter $0

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.