Shahboz
Shahboz

Reputation: 546

How to assign a Powershell function as an argument to a different function's parameter

So, I have two functions: First function:

function FunctionExecutor
{
    param
    (
        $function
    )
}

Second function is this:

function StartSSHsession
{   
    Write-Host "Hi"
}

Question: How do I execute the StartSSHSession by passing it into FunctionExecuter?

This is executing nothing.

FunctionExecutor -function: StartSSHsession

Upvotes: 2

Views: 218

Answers (2)

mklement0
mklement0

Reputation: 437062

PowerShell's way of passing code around is by way of script blocks (instances of type [scriptblock], which you can literally create and pass as { ... } and execute with &, the call operator.

Therefore, define your function as follows:

function CodeExecutor
{
    # Make the function an *advanced* function, which prevents attempts to
    # use undeclared parameters.
    [CmdletBinding()] 
    param
    (
        # Define the piece of functionality to accept as a [scriptblock]
        [scriptblock] $ScriptBlock
    )

    # Invoke the script block with `&`
    & $ScriptBlock
}

Now, after defining StartSSHsession...

function StartSSHsession {
   param(
     $Foo
   )
   Write-Host "Hi: $Foo"
}

... you can pass it to CodeExecutor as follows, using a script block with arguments:

CodeExecutor -ScriptBlock { StartSSHsession Bar }

... which yields:

Hi: Bar

Alternatively, you could pass the arguments to pass to the script block separately, as arguments to CodeExecutor directly, which could then pass it on as & $ScriptBlock ...


As for what you tried:

This is executing nothing.
FunctionExecutor -function: StartSSHsession

You're not showing us what you're doing with parameter $Function inside FunctionExecutor, but, in the absence of explicit typing of the parameter, the specific token passed - StartSSHsession - is interpreted as a string [System.String].

Upvotes: 1

G42
G42

Reputation: 10019

One way is to dot-source:

function FunctionExecutor
{
    param
    (
        $function
    )
    . $function
}

Bear in mind you're only passing in the name.


An example using an additional Switch parameter and using $PSBoundParameters automatic variable:

function StartSSHsession
{   
    param(
        [switch]$useEmail
    )
    if($useEmail){
        Write-Host "Use Email"
    }else{
        Write-Host "Hi"
    }
}

function FunctionExecutor
{
    param
    (
        [switch]$useEmail,
        $function
    )
    . $function @PSBoundParameters
}

Upvotes: 1

Related Questions