1

Consider the following function

Function IfFunctionExistsExecute
{
    param ([parameter(Mandatory=$true)][string]$func)
    begin 
    {
        # ...
    }
    process
    {
        if(Get-Command $func -ea SilentlyContinue)
        {
            & $func # the amperersand invokes the function instead of just printing the variable
        }
        else
        {
            # ignore
        }       
    }
    end
    {
        # ...
    }
}

Usage:

Function Foo { "In Foo" }
IfFunctionExistsExecute Foo

This works.

However this doesn't work:

Function Foo($someParam) 
{ 
     "In Foo"
     $someParam
}

IfFunctionExistsExecute Foo "beer"

However this gives me the ugly error:

IfFunctionExistsExecute : A positional parameter cannot be found that accepts argument 'beer'.
At C:\PSTests\Test.ps1:11 char:24
+ IfFunctionExistsExecute <<<<  Foo "beer"
    + CategoryInfo          : InvalidArgument: (:) [IfFunctionExistsExecute], ParameterBindingException
    + FullyQualifiedErrorId : PositionalParameterNotFound,IfFunctionExistsExecute

How can I do this in PS?

3 Answers 3

2

Try creating an optional parameter on the function your calling, and on your IfFunctionExistsExecute function; something like this:

Function IfFunctionExistsExecute
{
    param ([parameter(Mandatory=$true)][string]$func, [string]$myArgs)
        if(Get-Command $func -ea SilentlyContinue)
        {
            & $func $myArgs  # the amperersand invokes the function instead of just printing the variable
        }
        else
        {
            # ignore
        }       
}

Function Foo
{ 
    param ([parameter(Mandatory=$false)][string]$someParam)
    "In Foo" 
    $someParam
}

IfFunctionExistsExecute Foo
IfFunctionExistsExecute Foo "beer"

For me this gives:

C:\test>powershell .\test.ps1
In Foo

In Foo
beer

C:\test>
Sign up to request clarification or add additional context in comments.

2 Comments

Seems that the issue was that my module wasn't being reloaded when I edited it :(
don't use $args as your own parameter name , as that is a built in automatic parameter name.
1

Maybe you should pass arguments to the called function as well:

$arguments = $args[1..($args.Length-1)]
& $func @arguments

2 Comments

Nope, doesn't do the trick, same error... I even tried to add the $args to the param list of the IfFunctionExistsExecute method.
Ok, it works half, the @ thingy (whatever that does) passes it in as comma seperated, like this: Foo b,e,e,r. Which is not what I want.
1

I wrote my solution. Function named by powershell's style: Verb-Noun. It supports named parameters and remaining arguments.

function Invoke-FunctionIfExist {
    [CmdletBinding()]
    param (
        # Function name
        [Parameter(Mandatory, Position=0)]
        [string]
        $Name,
        # Hashtable with named arguments
        [Parameter()]
        [hashtable]
        $Parameters = @{},
        # Rest of arguments
        [Parameter(ValueFromRemainingArguments)]
        [object[]]
        $Arguments = @()
    )

    process {
        if (Get-Command $Name -ErrorAction SilentlyContinue) {
            & $Name @NamedArguments @Arguments
        }
    }
}

Usage example:

PS> Invoke-FunctionIfExist Foo
In Foo
PS> Invoke-FunctionIfExist Foo beer
In Foo
beer
PS> Invoke-FunctionIfExist Foo -Parameters @{someParam='beer'}
In Foo
beer

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.