Кажется, что Powershell получает неверное количество элементов в массиве параметров - PullRequest
0 голосов
/ 17 января 2019

Предположим, у меня есть (в файле test.ps1):

param (
    [string[]] $one
)
Write-Host $one.Count

Если я это сделаю:

powershell -File test.ps1 -one "hello","cat","Dog"

Я получаю:

1

Но я ожидаю:

3

Почему?

Ответы [ 2 ]

0 голосов
/ 18 января 2019

В дополнение Полезный ответ Кевина Смита :

  • Единственный способ передать массив в сценарий PowerShell через интерфейс командной строки PowerShell (powershell.exe; pwsh для PowerShell Core ) должен использовать -Commmand.

    • В отличие от этого, -File интерпретирует аргументы как буквенные значения и не распознает массивы, ссылки на переменные ($foo), .. . в данном случае скрипт заканчивает тем, что видит одну строку с буквальным содержимым hello,cat,Dog (из-за удаления двойных кавычек).
  • С внутри PowerShell :

    • Используйте -Command с блоком сценария ({ ... }), как показано в ответе Кевина , что не только упрощает синтаксис (просто используйте обычный синтаксис внутри блока), но выдает вывод с богатым типом (не просто строки , как с другими внешними программами), потому что целевой экземпляр PowerShell использует формат сериализации CLIXML для вывода своих результатов, что вызывающий сеанс автоматически десериализуется, так же, как работают удаленные / фоновые задания PowerShell (однако, как и в случае с последним, точность десериализации всегда ограничена).

    • Обратите внимание, однако, что из PowerShell вам обычно не нужен CLI , который создает (дорогостоящий) дочерний процесс и может просто вызвать *.ps1 файл сценария напрямую :

      • .\test.ps1 -one hello, cat, Dog
  • С за пределами PowerShell - обычно cmd.exe / пакетный файл - использование -Command с одинарной строкой в ​​двойных кавычках , содержащий код PowerShell для выполнения, учитывая, что с использованием блоков сценариев не поддерживается извне .

    • powershell -Command ".\test.ps1 -one hello, cat, Dog"

Обратите внимание, что при -Command, как и при прямом вызове внутри PowerShell, вы должны использовать .\test.ps1 вместо test.ps1, чтобы выполнить файл с таким именем в текущий каталог , который является функцией безопасности.

Также обратите внимание, что с вашими простыми значениями аргументов "..." -объединение их является необязательным, поэтому в вышеприведенных командах используется hello, cat, Dog вместо "hello", "cat", "Dog"; фактически используя встроенные символы ". В общем * командная строка "..." может быть довольно сложной - смотрите этот ответ .

0 голосов
/ 17 января 2019

"- one" передается как целая строка, поскольку преобразование происходит перед вызовом метода.

Вы можете также назвать это следующим образом

powershell -Command {.\test.ps1 -one "hello","cat","Dog"}
...