4

I have been unable to create a Powershell function that accepts more than one scriptblock parameter. Here's the simplified test script. What is the issue with multiple scriptblocks?

function Task1 {
    param([scriptblock]$f={})

    $f.Invoke()
}

function Task2 {
    param([scriptblock]$f={}, [scriptblock]$k={})

    $f.Invoke()
    $k.Invoke()
}

Task1({write-host "hello" -nonewline })
Task1({write-host " world" })
Task2({write-host "hello" -nonewline }, { write-host " world" })

This produces the following output:

hello world
Task3 : Cannot process argument transformation on parameter 'f'. Cannot convert the "System.Object[]" value of type "S
ystem.Object[]" to type "System.Management.Automation.ScriptBlock".
Lars Truijens
  • 42,837
  • 6
  • 126
  • 143
BC.
  • 24,298
  • 12
  • 47
  • 62

2 Answers2

10

Your problem is that you are using parentheses and commas when calling functions, a common mistake in powershell.

These should work:

Task1 {write-host "hello" -nonewline } 
Task1 {write-host " world" }
Task2 {write-host "hello" -nonewline }  { write-host " world" }
Mike Shepard
  • 17,466
  • 6
  • 51
  • 69
3

You can also invoke the scriptblock with the PowerShell call operator '&'. As an alternative, I removed the type information and initialization of that parameters. This would produce different errors if a scriptblock was not passed.

function Task1 {
    param($f)

    & $f
}

function Task2 {
    param($f,$k)

    & $f
    & $k
}

Task1 {write-host "hello" -nonewline }
Task1 {write-host " world" }
Task2 {write-host "hello" -nonewline } { write-host " world" }
Doug Finke
  • 6,675
  • 1
  • 31
  • 47