Передача массива в другой скрипт с помощью Invoke-Command

Я застрял, пытаясь понять это. Я видел другие статьи и перепробовал все, но ничего не получается. Я пытаюсь передать массив в качестве аргумента другому сценарию PS. Вот что я пытаюсь:

$IPArray = Get-Content C:\ListofIps.txt
Invoke-Command -Computername $server -Credential $cred -FilePath "C:\script.ps1" -ArgumentList (,$IPArray)

5 значений в $IPArray не передаются сценарию, который я вызываю.

Заранее спасибо, ребята, я очень ценю любую помощь, которую вы можете оказать...


person Sameer    schedule 10.07.2013    source источник
comment
Почему у вас есть запятая перед $IPArray и почему вы заключаете ее в круглые скобки? Если вы просто хотите передать $IPArray в качестве списка аргументов, используйте -ArgumentList $IPArray.   -  person Adi Inbar    schedule 10.07.2013
comment
Спасибо за быстрый ответ, Ади. Согласно этой теме, круглые скобки и запятая необходимы для -ArgumentList для просмотра аргумента в виде массива. Однако я пробовал оба способа, и ни один из них не работал.   -  person Sameer    schedule 10.07.2013
comment
Есть ли в script.ps1 инструкция param() для приема аргументов? Попробуйте проверить это, поместив в файл test.ps1 на $server следующее: param([string[]$IPs) $IPS | Write-Output Это должно, по крайней мере, сказать, правильно ли передается аргумент и принимается ли он целевым сценарием.   -  person jbsmith    schedule 10.07.2013
comment
Похоже, это было так, JBSmith! Ранее я уже пробовал оператор param, но не знал, что это должна быть первая исполняемая строка во втором скрипте. Это дает мне то, что мне нужно, но должен ли я вообще передавать $IPArray как -ArgumentType? Разве она не должна быть глобальной переменной при вызове сценария test.ps1?   -  person Sameer    schedule 10.07.2013
comment
$IPArray находится в глобальной области видимости в вашем текущем локальном сеансе. Но когда вы запускаете Invoke-Command, вы запускаете новую сессию на удаленном компьютере. На этом компьютере нет никаких локальных переменных, функций, модулей и т. д. из вашего локального сеанса. В powershell версии 3 появилась новая область переменных, называемая using, которая может передавать локальные переменные в удаленные сеансы. Итак, вы должны указать переменную в своем скрипте следующим образом: $using:IPArray. Но в версии 2 вы должны использовать -ArgumentList, чтобы передать локальные переменные на удаленную машину.   -  person jbsmith    schedule 11.07.2013
comment
Вакансии имеют такое же ограничение. Они кажутся родственными.   -  person js2010    schedule 30.10.2019


Ответы (3)


Использовать:

... -ArgumentList (,$IPArray)

Поскольку параметр ArgumentList ожидает массив, вы правильно заметили, что вам нужно обернуть массив в другой массив. Однако правильный синтаксис в этом сценарии (указание значения параметра) заключается в использовании выражения группировки () для создания вложенного массива.

person Keith Hill    schedule 10.07.2013
comment
Первая запятая не нужна, если вы используете @($IPArray). - person ashes999; 10.02.2014
comment
@() ничего не делает с массивом. То есть, если содержимое @() является скаляром, то этот скаляр помещается в массив, но если содержимое уже является массивом, этот массив не помещается в дополнительный массив. - person Keith Hill; 10.02.2014
comment
Интересно, я этого не знал. Спасибо. - person ashes999; 10.02.2014

Это старый вопрос, но я собираюсь повторить @keith-hill в ответе — добавить запятую в начале объявления массива (даже при включении существующего массива).

Это глупо, но я отвечаю снова, потому что перепробовал все альтернативы, и это единственное, что работает, даже с PowerShell 3.0+. Вы можете использовать #require для чего угодно, по крайней мере, версии 3.0+, но ничего не будет работать, если вы не сделаете то, что предлагает @keith-hill - даже если это массив, а параметр - массив, PS в этом случае отстой (и я люблю PS) ... делайте то, что он сказал (публикация не сработала, извините, но рабочие ответы лучше): \ ... -ArgumentList (,$IPArray)

Это не имеет смысла, но это работает. Руки вниз к команде PS за сброс бомбы на это, но если бы я этого не сделал, мой сценарий был бы недействителен. И я стал "сценаристом"... так что вот.

person areyling    schedule 12.07.2017
comment
ДЕЙСТВИТЕЛЬНО хотел отредактировать это, но, честно говоря, ваше исправление не работает ... может быть, для вас, но не для всех остальных. Хотя хотелось бы узнать о вашей проблеме... - person areyling; 12.07.2017
comment
Это не совсем глупо. Происходит следующее: -ArgumentList по умолчанию берет массив и распределяет элементы по параметрам в вызванной команде: Invoke-Command -ScriptBlock { param($x, $y, $z) ... } -ArgumentList (1, 2, 3) устанавливает $x в 1, $y в 2, $y, $z в 3. Итак, -ArgumentList уже имеет специальную обработку массивов; это принципиально, как это работает. Когда вы передаете свой собственный массив, он не может определить разницу между вашим и, например. (1, 2, 3), поэтому он берет элементы вашего массива и распределяет их. Синтаксис (, $x) позволяет получить массив с 1 элементом, и этот элемент является вашим массивом. - person Jonathan Gilbert; 30.05.2019

Если вы просто пытаетесь передать один массив, вы можете рассматривать саму переменную $args как массив в вашей удаленной команде, и вы получите тот же результат, что и при передаче ее как (, $IPArray), а затем доступ к этому массиву в блоке скрипта как $ аргументы[0]. Я не проверял, работает ли это с несколькими массивами или нет.

То есть,

$MyScriptBlock = { $args | % { Do-Stuff -Thing $PSItem } }
Invoke-Command -Session $MySession -ScriptBlock $MyScriptBlock -ArgumentList $IPArray

вернет те же значения, что и

$MyScriptBlock = { $args[0] | % { Do-Stuff -Thing $PSItem } }
Invoke-Command -Session $MySession -ScriptBlock $MyScriptBlock -ArgumentList (,$IPArray)
person chefchaouen    schedule 01.05.2021