Can I create an array of functions in Powershell?

Viewed 1659

I would like to have an array that contains a set of functions that I can iterate through and call. The issue is that the functions all run via the line that adds them to the array (ie. $scripts).

Example:

function Hello
{
    $BadFunction = "Hello"
    Write-Host "Hello!"
}

function HowAreYou
{
    $BadFunction = "HowAreYou"
    Write-Host "How are you?"
    #$false = $true
}

function Goodbye
{
    $BadFunction = "Goodbye"
    Write-Host "Goodbye!"
}

$scripts = @((Hello), (HowAreYou), (Goodbye))

foreach ($script in $scripts)
{
    $script
}
2 Answers

Functions can only be called by using their name, not referenced, but you can get the scriptblock via the Function: drive:

$scripts = $Function:Hello, $Function:HowAreYou, $Function:GoodBye

# call them with the & operator
$scripts | ForEach-Object { & $_ }

# You can also call them by calling Invoke on the scriptblock
$scripts | ForEach-Object Invoke

Joey's answer contains good information, but if all you need is to reference your functions by name, define your array as containing the function names as strings, and invoke the functions by those strings with &, the call operator:

function Hello {  "Hello!" }

function HowAreYou { "How are you?" }

function Goodbye { "Goodbye!" }

# The array of function names *as strings*.
# Note that you don't need @(...) to create an array.
$funcs = 'Hello', 'HowAreYou', 'Goodbye'

foreach ($func in $funcs)
{
  # Use & to call the function by the name stored in a variable.
  & $func
}

The issue is that the functions all run via the line that adds them to the array (ie. $scripts).

That's because your array elements are expressions (due to the enclosing (...)) that call the functions (e.g., (Hello) calls Hello and makes its output the array element), given that they're being referenced without single- or double-quoting.

Unlike in, say, bash, you cannot define string array elements as barewords (tokens without enclosing single- or double-quoting); for instance, the following is a syntax error in PowerShell:

# !! Does NOT work - strings must be quoted.
$funcs = Hello, HowAreYou, GoodBye # ditto with @(...)
Related