I was asked recently to clarify the different uses of parenthesis in PowerShell:
I struggle with $myvar.foo vs. ($myvar).foo vs. ($myvar).foo() vs. $myvar.foo(); vs. $myvar.foo(1), etc., etc.
How do I know which one to use for which case? And then how to put this output into a write-output statement?
There are basically three ways of using parenthesis in PowerShell: grouping, method calls, and sub-expressions. Hopefully the explanations and examples below will help. Feel free to ask questions in the comments if I’ve missed something.
The simplest use of parenthesis is similar to the mathematics use of grouping constructs. In fact, in it’s simplest form, it’s exactly the same as what you learned in math, and we use it to group calculations to determine the order of operations:
2 + (2 * 4) # Output: 10
(2 + 2) * 4 # Output: 16
But in PowerShell, it can also group calls to cmdlets and functions, and can allow you to invoke methods and properties on the output of those cmdlets. This allows you to use operators or call methods on the output of cmdlets without first storing them in variables. You can add and subtract dates:
When doing a registry lookup, you can avoid getting all of the PS* properties, you can call a single property, for instance, to get the path to PowerShell.exe:
You can cast the output of a command to another type. So for instance, if you wanted to pick 10 random letters, you might use the fact that 65..90 are the ASCII values for A..Z, and then cast them to the char type:
Tips and Tricks
One side effect of this particular use of parentheses is that you can use them to cause an assigned value to leak: that is, you can assign the output of a command to a variable, and still output it. So for instance, this script actually returns 14 and 28:
$seven * 3
This is obviously a really useful shortcut sometimes, now that you know about it ...
All objects have methods. In order to invoke a method, you have to use parenthesis to “call: it. So for instance, strings have a bunch of different methods, which you can see with this command:
For instance to convert a string to all upper case, you call the ToUpper method:
Note that when you type the name of a method without the parenthesis, you don’t invoke it:
"hi".ToUpper Instead, PowerShell does reflection on the method and gives you information about how to call it, what the overloads are, etc. You can see much of the same information in the output of
Get-Member. When you have a method that takes parameters, you need to pass the parameters inside the parenthesis, separating them with commas if there’s more than one:
"This is a test".IndexOf("i", 3) # start looking at 2, so returns 5, the NEXT i
PowerShell also has another way to use parenthesis: with a leading $ (dollar sign), they become a sub-expression, which is calculated before the containing expression … so for instance, you will notice that the Write-Host inside the sub expression will output first:
Of course, you can’t put two command pipelines (separated by the semicolon “;”) into a simple parenthesis, but you can in a sub-expression!