1

I'm trying to pass a function to a method and then pass parameters to the method I passed when calling it, but if I pass more than one parameter then the method fails with an error:

function debugMeStuffs($someBlah, $somePoo) {

    Write-Host $someBlah            
    Write-Host $somePoo
}


function invokeOnHosts ([scriptblock]$funcToCall, $param1, $param2, $startRange, $endRange) {
#Param($funcToCall)

$i = $startRange

for($i = [int]$startRange; $i -le $endRange; $i++) {

    # HOW DO I MAKE THIS WORK WITH MULTIPLE PARAMETERS?!?!?!?
    $funcToCall.Invoke('blah' 'poo')
}
}

invokeOnHosts $function:debugMeStuffs "param1" "param2" 4 7

Things I've tried:

  • $funcToCall("blah" "poo")
  • $funcToCall('blah' 'poo')
  • $funcToCall.Invoke("blah" "poo")
  • $funcToCall.Invoke('blah' 'poo')
  • $funcToCall 'blah' 'poo'
  • $funcToCall.Invoke 'blah' 'poo'
  • $funcToCall "blah" "poo"
  • $funcToCall.Invoke "blah" "poo"

None of the above seem to work. Is there something else I need to do to make this work?

leeand00
  • 25,510
  • 39
  • 140
  • 297

1 Answers1

2

.Invoke() is a .NET method, so the usual method-call syntax applies: you need

  • parentheses - (...) - around the list of arguments
  • you must separate the arguments with ,
$funcToCall.Invoke('blah', 'poo')

This contrasts with PowerShell's own syntax for calling cmdlets and functions, which is shell-like[1]:

  • no (...) around the argument list

  • arguments must be separated with spaces.

& $funcToCall blah poo  # equivalent of the method call above.

A command such as the above is parsed in argument mode, which is why quoting the arguments in this simple case is optional.

Note the need for &, PowerShell's call operator, which is needed to execute the script block stored in $funcToCall; this is generally necessary for invoking a command stored in a variable, and also for command names / paths that are quoted.


Given that it's easy to get confused between PowerShell's command syntax and .NET's method syntax, it's best to stick with PowerShell-native features[2], if possible.
That said, being able to call methods on .NET types directly is a wonderful extensibility option.

To help avoid accidental use of method syntax when calling PowerShell commands, you can use Set-StrictMode -Version 2 or higher, but note that that entails additional strictness checks.


[1] PowerShell is, after all, a shell - but it is also a full-featured scripting language that offers near-unlimited access to the .NET framework.
Reconciling these two personalities is a difficult balancing act, and the shell-like command-invocation syntax is a frequent problem for newcomers with a programming background, given that the rest of the language looks like a traditional programming language and that calling methods on .NET types does use the traditional syntax.

[2] This means preferring PowerShell's cmdlets, functions, and operators to use of the underlying .NET types' methods; doing so also usually provides rewards you with operating at a higher level of abstraction.

mklement0
  • 382,024
  • 64
  • 607
  • 775