Invoke-Command с именем динамической функции

Я нашел этот замечательный пост: Использование Invoke-Command -ScriptBlock на функция с аргументами

Я пытаюсь сделать вызов функции (${function:Foo}) динамическим, так как я хочу передать имя функции.

Я пробовал это:

$name = "Foo"
Invoke-Command -ScriptBlock ${function:$name}

но это не удается. Я также пробовал различные escape-последовательности, но просто не могу сделать имя функции динамическим.


РЕДАКТИРОВАТЬ: Для ясности я добавляю небольшой тестовый скрипт. Конечно, желаемый результат - вызвать функцию ExternalFunction.

Function ExternalFunction()
{
  write-host "I was called externally"
}

Function InternalFunction()
{
    Param ([parameter(Mandatory=$true)][string]$FunctionName)
    #working: Invoke-Command -ScriptBlock ${function:ExternalFunction}
    #not working: Invoke-Command -ScriptBlock ${invoke-expression $FunctionName}
    if (Test-Path Function:\$FunctionName) {
    #working,but how to use it in ScriptBlock?
    }
}

InternalFunction -FunctionName "ExternalFunction"

person Dennis G    schedule 09.02.2013    source источник


Ответы (3)


Альтернативное решение:

function foo {'I am foo!'}

$name = 'foo'

$sb = (get-command $name -CommandType Function).ScriptBlock
invoke-command -scriptblock $sb

я фу!

person mjolinor    schedule 09.02.2013
comment
Я не имел в виду, что вы должны добавить рабочий пример. Я был рад, что приведенный вами пример сработал! :-) Спасибо - person Dennis G; 10.02.2013
comment
Просто для справки в будущем, это на самом деле не удастся, если вы используете его с расширенной функцией, которая имеет блок «Начало», «Обработка» или «Конец». Вы получите исключение о содержании более одного предложения. Вы можете обойти это, используя оператор вызова вместо Invoke-Command. Что-то вроде этого: & $sb Некоторый аргумент функции - person user2233949; 28.06.2017

Вы можете попробовать следующее. Он проверяет, является ли указанное имя допустимой функцией, прежде чем пытаться ее запустить:

$myfuncnamevar = "Foo"
Invoke-Command -ScriptBlock {
    param($name)
    if (Test-Path Function:\$name) { 
        #Function exists = run it
        & $name
    }
} -ArgumentList $myfuncnamevar
person Frode F.    schedule 09.02.2013
comment
Test-Path работает, но как мне его вызвать в Invoke-Command? - person Dennis G; 09.02.2013
comment
Я поставил строку внизу, чтобы объяснить это. Обновлено с решением сейчас. Помните, что функция должна существовать на удаленном компьютере. Если это локальная функция, вам нужно передать ее в блоке сценария. - person Frode F.; 09.02.2013

так просто как :

invoke-expression  $name

или если вы хотите сохранить команду вызова для удаленного взаимодействия, например

Invoke-Command -ScriptBlock { invoke-expression  $name}
person Loïc MICHEL    schedule 09.02.2013
comment
invoke-expression работает вне функции. Но при использовании его вместе с командой вызова внутри функции я получаю "Cannot validate argument on parameter 'ScriptBlock'. The argument is null. Supply a non-null argument and try the" - person Dennis G; 09.02.2013
comment
у вас есть нежелательный $ перед вашим скриптовым блоком - person Loïc MICHEL; 09.02.2013