Пользовательский модуль PowerShell и набор функций для передачи на удаленные компьютеры

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

Я написал собственный модуль, в котором есть единственный файл функции. Структура следующая:

  • C:\PowerShell-Modules\ModuleName
    • C:\PowerShell-Modules\ModuleName.psd1
    • C:\PowerShell-Modules\MyFunction.ps1 (contains a function called MyFunction).

Чтобы полагаться на автоматическую загрузку модулей, я изменяю $env:PSModulePath, чтобы он содержал «C:\PowerShell-Modules\».

В моем сценарии (например, PassRemote.ps1) «MyFunction» доступна и работает, как и ожидалось. Однако при попытке запустить это на удаленном компьютере:

Invoke-Command -ComputerName $computername -UseSSL -ScriptBlock ${function:MyFunction} -ArgumentList $arg1

... происходит сбой, сообщая, что командлет/функция не распознана.

Единственный способ, которым я могу передать пользовательскую функцию, - это явно загрузить модуль в скрипт. Чтобы было ясно, мне нужно написать строку:

Import-Module ModuleName 

в родительском скрипте (PassRemote.ps1). Только после этого функция может быть передана удаленному сеансу.

Это проблема масштаба?


person Robin    schedule 18.09.2014    source источник
comment
Процесс в удаленном сеансе не powershell.exe, а wsmprovhost.exe, возможно, автоматическая загрузка не поддерживается при удаленном взаимодействии.   -  person walid toumi    schedule 18.09.2014
comment
Спасибо за ответ. Как уже упоминалось, если я вручную загружаю модуль в родительский скрипт, я могу передать функцию удаленному компьютеру (поэтому мне не нужно использовать модификатор using). Однако я не хочу вручную загружать модули. Однако я думаю, что наткнулся на причину. Я напишу предлагаемый ответ ниже.   -  person Robin    schedule 18.09.2014


Ответы (1)


Похоже, что явная загрузка модуля также загружает все содержимое функций/командлетов внутри него (то есть сам код). Таким образом, функции доступны для передачи целиком.

Если полагаться на автоматическую загрузку модулей, загружаются только имена доступных командлетов/функций (очевидно, иначе загрузка PS3+ при запуске заняла бы довольно много времени). Это означает, что хотя сеанс PS «осведомлен» об автоматически загружаемых функциях, в этот момент у него фактически нет кода для передачи в удаленный сеанс. К сожалению, использование «-ScriptBlock ${function:MyFunction}», по-видимому, не приводит к принудительному расширению или загрузке этой функции, чтобы она была доступна для прохождения.

Чтобы доказать приведенную выше теорию (и избежать явной загрузки модуля), мы можем запустить:

    $x = Get-Command MyFunction

а потом:

Invoke-Command -ComputerName $computername -UseSSL -ScriptBlock ${function:MyFunction} -ArgumentList $arg1

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

person Robin    schedule 18.09.2014