Вы делаете две очень маленькие вещи неправильно:
Метод называется InvokeScript
, так что буквально то, что вы передаете, является scriptblock
.
Прямо сейчас, ваш ScriptBlock
в основном так:
$args = @(<random stuff>) # this line is implicit of course,
# and $args will have the value of whatever your _psObjects has
Out-String
Таким образом, если вы можете сказать аргументы, приведенные в сценарии, вы просто не используете их. Таким образом, вы хотите что-то более похожее на это в качестве сценария:
Out-String -InputObject $args
Только теперь проблема в том, что Out-String
на самом деле не нравится, когда ему присваивают Object[]
как -InputObject
, поэтому вместо этого ваш сценарий должен выглядеть примерно так:
$args | Out-String
Или что-то вроде этого, например использование foreach
, вы поймете идею.
Ваша вторая ошибка в том, что вы передаете _psObjects
на неправильный параметр - это должно быть:
this.SessionState.InvokeCommand.InvokeScript(<ScriptBlock>, true, PipelineResultTypes.None, null, _psObjects);
Официальная документация очень плохая, и я абсолютно не знаю, для чего нужен другой параметр.
В одной из перегрузок есть списки:
input
= необязательный ввод для команды
args
= Аргументы для передачи в scriptblock
Но при следующей перегрузке он говорит следующее:
input
= Список объектов для использования в качестве входных данных для script .
args
= Массив аргументов для команды .
Все, что я могу вам сказать, это в моих тестах это работает, когда я делаю это, как указано. Надеюсь, что это поможет!
Для справки, проверенный и рабочий код PS:
function Test
{
[CmdletBinding()]
param()
$results = $PSCmdlet.SessionState.InvokeCommand.InvokeScript('$args | Out-String', $false, "None", $null, "Hello World!")
foreach ($item in $results)
{
$item
}
}
Test
РЕДАКТИРОВАТЬ
Я должен добавить, что согласно моим тестам, если вы передадите что-то как input
, так и args
, то $args
будет пустым внутри скрипта. Как я уже сказал, на самом деле не знаю, что делает input
, просто передайте ему null
.
РЕДАКТИРОВАТЬ 2
Как уже упоминалось tig, на PowerShell, выпуск 12137 , все, что будет передано input
, будет связано с переменной $input
внутри блока сценария, что означает, что можно использовать input
или args
.
сказал ... будьте осторожны с использованием $input
- это коллекция, которая будет содержать больше, чем то, что передается с помощью параметра input
: в соответствии с моими тестами индекс 0 будет содержать bool
, то есть то, что передано на 2-й параметр InvokeScript()
и индекс 1 будут содержать PipelineResultTypes
, то есть все, что было передано InvokeScript()
по 3-му параметру.
Также я бы не рекомендовал использовать PowerShell.Create()
в этом случае: зачем создавать новый экземпляр PowerShell, когда у вас есть PSCmdlet
, что означает, что он у вас уже есть?
Я все еще думаю, что использование args
/ $args
- лучшее решение. Конечно, вы также можете сделать вещи намного приятнее (хотя в этом случае совершенно не нужны), используя ScriptBlock, например:
[CmdletBinding()]
param
(
[Parameter(Mandatory)]
[PSObject[]]
$objects
)
Out-String -InputObject $objects
Это будет быстрее, так как вы больше не полагаетесь на (медленный) трубопровод.
Только не забывайте, что теперь вам нужно обернуть _psObjects
вокруг object[]
как:
this.SessionState.InvokeCommand.InvokeScript(<ScriptBlock>, true, PipelineResultTypes.None, null, new object[] {_psObjects});