0

I have common helper etc methods on script library, i'd like to use them directly over powershell remoting, how ever i don't know how to pass them to scripts targeted to other machines.

I try pass function as scriptblock and execute it at remote server, on local computer everything works fine:

function test { write-host "abc" }
Invoke-Command -ScriptBlock {Param($1) & $1} -ArgumentList ${Function:Test}

Prints "abc"

However following does not work:

function test { write-host "abc" }
Invoke-Command -ScriptBlock {Param($1) & $1} -ArgumentList ${Function:Test} -ComputerName "OTHERCOMPUTER" -Credential $cred

The term ' write-host "abc" ' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again. + CategoryInfo : ObjectNotFound: ( write-host "abc" :String) [], CommandNotFoundException + FullyQualifiedErrorId : CommandNotFoundException

Any idea what is wrong?

Edit: For clarification following answer where function itself is defined in scriptblock does not apply because function is taken from common script file located only on computer where remote is used. They are like "GetConfigurationFromAppConfig","SelectFromDatabase" and so on.

If i write function to every script block, then i have to copypaste same code over and over again everywhere. I don't want to use "common" script location where every computer can load scripts inside block either (for example . "\SharedLocation\") because it is fragile (lots of depencies) and it must be made for every server targeted for remoting (lots of upkeep).

savpek
  • 1,372
  • 2
  • 14
  • 23
  • Just found a much better answer! http://stackoverflow.com/questions/8448808/using-invoke-command-scriptblock-on-a-function-with-arguments – Raf Mar 05 '14 at 15:15

3 Answers3

0

Invoke-Command -ScriptBlock {function test { write-host "abc" }; test} -ComputerName "OTHERCOMPUTER" -Credential $cred

Raf
  • 9,681
  • 1
  • 29
  • 41
  • Edited question, this is solution which i try to avoid. – savpek Feb 13 '14 at 11:08
  • Re: edit - you have to make the remote computer "aware" of the extra functions you are trying to execute by either including them in the script block or importing them via `import-module`. – Raf Feb 13 '14 at 11:24
0

Another option is to use [ScrtiptBlock]::Create() to build your script using the function definitions that are already declared in your local session. This saves you having to manually re-create all the code in the functions inside the remote script invocation:

function test { write-host "abc" }

$SB = [ScriptBlock]::Create(@"
function test {$Function:test}
test
"@)

$SB


function test { write-host "abc" }
test

Then just invoke $SB on the remote computer.

Edit:

Per the additional comments, if you have a library of script files on the remote computer where the functions are declared, you can just dot-source them in your script block:

$SB = {
. 'c:\scripts\myfunctions.ps1'
test
}

Invoke-Command -ScriptBlock $SB -ComputerName 'OTHERCOMPUTER'
mjolinor
  • 66,130
  • 7
  • 114
  • 135
0

In the instances where I need to leverage a library of custom functions/resources, I just use Import-Module within my scriptblock. This seems like the cleanest implementation to me....and I have access to hundreds of custom functions here at work.

websch01ar
  • 2,103
  • 2
  • 13
  • 22