Pass and execute local functions with arguments into a Scriptblock

I am writing an application that uses a function to handle data manupilation. At this point I need to execute a scriptblock on the remote computer that uses this function and receves it as a parameter. The code I am testing accomplishes this, but it throws back and error along with the correct result. Need a way to accomplish the same result without the error.

   function MyFunction{
      param ($String)
      Write-Output "this is: $String"   
   }

   $ScriptBlock = {
      param ($MyFunction, $String)           
      invoke-expression $MyFunction.ScriptBlock.Invoke($String)    
   }

   $MyFunction = (get-item function:MyFunction)
   $String = "123"
   Invoke-Command -ComputerName <RemoteComputerName> -ScriptBlock $ScriptBlock - 
   Credential $DomainCred -ArgumentList ($MyFunction,$String)

<p class=“lang-bsh prettyprint prettyprinted”>This is the result I am receiving - part result plus error message that I can’t suppress. Using Try/Catch, the result does not show up as if it is being sent into the error stream together with the error…</p>

   this is: 123
    Cannot convert '' to the type 'System.String' required by parameter 'Command'. Specified method is not supported.
        + CategoryInfo          : InvalidArgument: (:) [Invoke-Expression], ParameterBindingException
        + FullyQualifiedErrorId : CannotConvertArgument,Microsoft.PowerShell.Commands.InvokeExpressionCommand
        + PSComputerName        : <RemoteComputerName>

you don’t need an Invoke-Expression there. You are already invoking it using .Invoke()

Hi, kvprasoon, removing the invoke-expression throws the following error:

Method invocation failed because [System.String] does not contain a method named 'Invoke'.
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : MethodNotFound

yup, this is how you do it.

Coz, the $MyString passed through to Invoke-Command becomes just string when it reaches the remote computer, hence a rebuilt is required which can be done using ScriptBlock type. Once created use Invoke() method to execute it.

Hi, kvprasoon, thank you for that detail! Just had to make another minor tweak and it worked!

[ScriptBlock]::Create($MyFunction.ScriptBlock).Invoke($String)

Final Code - no errors:

function MyFunction{
    param ($String)
    Write-output "this is: $String" 
}

$ScriptBlock = {
    param ($MyFunction, $String) 
    [ScriptBlock]::Create($MyFunction.ScriptBlock).Invoke($String) 
}

$MyFunction = (get-item function:MyFunction)
$String = "123"
Invoke-Command -ComputerName <[RemoteComputerName]> -ScriptBlock $ScriptBlock -Credential $DomainCred -ArgumentList ($MyFunction,$String)

Great, you could use ${function:MyFunction} to get the content of the function and use just [ScriptBlock]::Create($Myfunction).Invoke()

Invoke-Command -ComputerName < RemoteComputerName> -ScriptBlock $ScriptBlock -Credential $DomainCred -ArgumentList (${function:MyFunction},$String)