Functional difference between ${variable} and $($variable)

Generally, when using Environment Variables I stick to ${env:foo}, but have used $($env:foo) in the past. These both seem to evaluate the same whenever I’ve used them. This seems to be the case for when I do $($foo) or ${foo} as well.

Is there a functional difference between using ${env:foo} or ${foo} and $($env:foo) or $($foo)?

yes, $() is called sub expression, this is mainly used to place an expression between a string.
eg:-

$Process = Get-Process | Select-Object -First 1

Write-Output -InputObject "Process ID is $Process.Id" # Without subexpression

Write-Output -InputObject "Process ID is $($Process.Id)" # With subexpression

${} is used when we use space or any other characters in variable which cannot be normally used, this is also used as provider paths.

${This is also a variable} = 'Variable Value'
${This is also a variable}

Function TestFunction {
 Write-Output -InputObject "Empty Function"
}

${Function:TestFunction} # This returns the function content as scriptblock for function provider

'test file' > c:\temp\test.txt
${c:\temp\test.txt} # gets the content of the file for filesystem provider

# for available providers
Get-PSProvider

Thanks for the concise and informative answer! ${function:} is new to me and super helpful!

For simple variables, is there any difference in how they’re parsed? IE:

$foo = "bar"
Write-Output $foo
Write-Output $($foo)
Write-Output ${foo}

All seem to yield identical results. Is the only difference here style?

When calling properties of the object, clearly there’s a difference:

$foo = Get-Process "SomeFilter"
Write-Output $Foo.ProcessName
Write-Output $($foo.ProcessName)
Write-Output ${foo}.ProcessName

Gives the list of ProcessNames, ${foo.ProcessName} does nothing because 'foo.ProcessName' as a variable doesn’t exist.

I guess the heart of my question is, should I be always using $($foo) instead of ${foo} when using simple variable names? Is there anything wrong with using ${foo}?

I’m not sure what I did to my last post, but it seems to be in my history, but not on the thread, so here it is again:

Thanks for the concise and informative answer! ${function:} is new to me and super helpful!

For simple variables, is there any difference in how they’re parsed? IE:

$foo = "bar"
Write-Output $foo
Write-Output $($foo)
Write-Output ${foo}

All seem to yield identical results. Is the only difference here style?

When calling properties of the object, clearly there’s a difference:

$foo = Get-Process "SomeFilter"
Write-Output $Foo.ProcessName
Write-Output $($foo.ProcessName)
Write-Output ${foo}.ProcessName

Gives the list of ProcessNames, ${foo.ProcessName} does nothing because foo.ProcessName as a variable doesn’t exist.

I guess the heart of my question is, should I be always using $($foo) instead of ${foo} when using simple variable names? Is there anything wrong with using ${foo}?

$() sub expressions are never used until there is a requirement to use access members of an object inside quotes. And ${} also either for provider paths or variables with specific names which are normally not supported in variables names. Otherwise its only $ to be used. But there is no hard rule as $() and ${} cannot be used for simple variable names.

Thanks! I don’t go out of my way to enclose variables in any form of brackets/braces, but for simple variables I think ${foo} looks better than $($foo), and if there’s no rule, or functional difference for simple variables, I’ll keep at it.

Thanks for your detailed explanations!

$( ) has other uses too. You can combine multiple statements into one.

echo hi; echo there | measure | % count
hi
1

$(echo hi; echo there) | measure | % count
2