Подтвердить что ты не робот

Как включить локально определенную функцию при использовании PowerShell Invoke-Command для удаленного доступа?

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

У меня есть ps1 script, у которого есть определенная в нем функция. Он вызывает функцию, а затем пытается использовать ее удаленно:

function foo
{
    Param([string]$x)

    Write-Output $x
}

foo "Hi!"

Invoke-Command -ScriptBlock { foo "Bye!" } -ComputerName someserver.example.com -Credential [email protected]

Этот короткий пример script печатает "Привет!" а затем выдается сообщение: "Термин" foo "не распознается как имя командлета, функции, файла script или исполняемой программы".

Я понимаю, что функция не определена на удаленном сервере, потому что она не находится в ScriptBlock. Я мог бы переопределить его там, но я бы предпочел. Я хотел бы определить функцию один раз и использовать ее либо локально, либо удаленно. Есть ли хороший способ сделать это?

4b9b3361

Ответ 1

Вам нужно передать функцию (не вызов функции в ScriptBlock).

У меня была такая же потребность только на прошлой неделе и нашла эту SO-дискуссию

Итак, ваш код станет:

Invoke-Command -ScriptBlock ${function:foo} -argumentlist "Bye!" -ComputerName someserver.example.com -Credential [email protected]

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

Ответ 2

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

$fooDef = "function foo { ${function:foo} }"

Invoke-Command -ArgumentList $fooDef -ComputerName someserver.example.com -ScriptBlock {
    Param( $fooDef )

    . ([ScriptBlock]::Create($fooDef))

    Write-Host "You can call the function as often as you like:"
    foo "Bye"
    foo "Adieu!"
}

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

$allFunctionDefs = "function foo { ${function:foo} }; function bar { ${function:bar} }"

Ответ 3

Вы также можете поместить функции (-ы), а также script в файл (foo.ps1) и передать это команде Invoke-Command с помощью параметра FilePath:

Invoke-Command –ComputerName server –FilePath .\foo.ps1

Файл будет скопирован на удаленные компьютеры и выполнен.