12

This question is a spin-off to a comment in another question Powershell fails to retrieve pwdLastSet from Active Directory

This is where I tried calling the function like this:

 Get-PwdLastSet('grz')

I received the following hint which I truly appreciate:

...first, don't use parentheses ( ) to call functions in PowerShell (it is valid syntactically but wrong semantically). The proper way to execute the function is just Get-PwdLastSet grz...

I get it. But I'd like to ask - why is that? What do the parentheses mean then?

GrzegorzOledzki
  • 998
  • 6
  • 21
  • 1
    Explanations: http://stackoverflow.com/questions/11060833/parenthesis-powershell-functions ; http://stackoverflow.com/questions/4988226/how-do-i-pass-multiple-parameters-into-a-function-in-powershell – Bill_Stewart Dec 09 '16 at 15:19
  • 3
    Because the parser will interpret the entire expression inside `()` as *a single argument*, so it completely breaks invocation of cmdlets where you need to pass in multiple parameter arguments – Mathias R. Jessen Dec 09 '16 at 16:26
  • This has cost every developer hours of wasted time. If Powershell weren't meant to have parenthesis, they should have required a SPACE after the function name. Seasoned programmers add parenthesis half the time without realizing it. – Brain2000 Dec 16 '18 at 22:33
  • Powershell arrays should require a @( ) in front of the parenthesis, but they do not. @(1,2) is equal to (1,2). The only time @ makes a difference is when there is only one element. So @(1) is an array and (1) is not. Ridiculous. – Brain2000 Dec 16 '18 at 22:44

1 Answers1

11

Powershell is a parsed and interpreted language. The interpreter see's parenthesis as a control structure and is not expected or required at the Call Site. Consider the following example function:

function test-function {

    param
    (
    [string]
    $string,

    [string]
    $word
    )

    "String: $string.  Word: $word"

}

The proper way to call this function is as follows:

Test-Function -String "Hello" -Word "World"

The creators of Powershell at Microsoft wanted to create a single new product that would replace the cmd shell and vbscript. One of the primary goals of Powershell was to standardize cmdlet naming, call site proceedure, switch naming, and output (as an object). Anecdotally, another primary focus was eliminating the security flaws of vbscript.

By default Powershell cmdlets are Overloaded so that the same example function can be called like so:

Test-Function "Hello" "World"

Both of those examples will output the following:

"String: Hello.  Word: World"

So what happens if we decide to use parenthesis at the call site?

Test-Function("Hello","World")

"String: Hello World.  Word:"

So what happened? Powershell interpreted our input as a single array containing two strings which were passed to the first (positionally) variable. To get the desired result using parenthesis you'd have to do this:

Test-Function("Hello")("World")

We're sending two controlled structures (by structure think object type. In this case they're both of the type [String]), as indicated by the parenthsis, to the function. It hits the eye wrong does it not?

I hope this helps with your understanding of why it's against the grain to use parenthesis when calling functions and cmdlets.

Colyn1337
  • 2,397
  • 2
  • 23
  • 40