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

Как передать логические значения в PowerShell script из командной строки

Мне нужно вызвать PowerShell script из командного файла. Один из аргументов script - это логическое значение:

C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -NoProfile -File .\RunScript.ps1 -Turn 1 -Unify $false

Ошибка команды со следующей ошибкой:

Cannot process argument transformation on parameter 'Unify'. Cannot convert value "System.String" to type "System.Boolean", parameters of this type only accept booleans or numbers, use $true, $false, 1 or 0 instead.

At line:0 char:1
+  <<<< <br/>
+ CategoryInfo          : InvalidData: (:) [RunScript.ps1], ParentContainsErrorRecordException <br/>
+ FullyQualifiedErrorId : ParameterArgumentTransformationError,RunScript.ps1

В настоящее время я использую строку для логического преобразования внутри моего script. Но как я могу передать логические аргументы в PowerShell?

4b9b3361

Ответ 1

Похоже, что powershell.exe не полностью оценивает аргументы script, когда используется параметр -File. В частности, аргумент $false рассматривается как строковое значение, аналогично приведенному ниже примеру:

PS> function f( [bool]$b ) { $b }; f -b '$false'
f : Cannot process argument transformation on parameter 'b'. Cannot convert value 
"System.String" to type "System.Boolean", parameters of this type only accept 
booleans or numbers, use $true, $false, 1 or 0 instead.
At line:1 char:36
+ function f( [bool]$b ) { $b }; f -b <<<<  '$false'
    + CategoryInfo          : InvalidData: (:) [f], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : ParameterArgumentTransformationError,f

Вместо использования -File вы можете попробовать -Command, который будет оценивать вызов как script:

CMD> powershell.exe -NoProfile -Command .\RunScript.ps1 -Turn 1 -Unify $false
Turn: 1
Unify: False

Как Дэвид предполагает, что использование аргумента switch также будет более идиоматичным, упрощая вызов, удалив необходимость явно передать логическое значение:

CMD> powershell.exe -NoProfile -File .\RunScript.ps1 -Turn 1 -Unify
Turn: 1
Unify: True

Ответ 2

Более четкое использование может заключаться в использовании параметров коммутатора. Тогда просто наличие параметра Unify означает, что он был установлен.

Так же:

param (
  [int] $Turn,
  [switch] $Unify
)

Ответ 3

Попробуйте указать тип вашего параметра [bool]:

param
(
    [int]$Turn = 0
    [bool]$Unity = $false
)

switch ($Unity)
{
    $true { "That was true."; break }
    default { "Whatever it was, it wasn't true."; break }
}

В этом примере по умолчанию $Unity - $false, если вход не указан.

Использование

.\RunScript.ps1 -Turn 1 -Unity $false

Ответ 4

Это более старый вопрос, но на самом деле ответ на него есть в документации по PowerShell. У меня была та же проблема, и на этот раз RTFM действительно решил ее. Почти.

https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_powershell_exe

Документация для параметра -File гласит, что "В редких случаях вам может потребоваться указать логическое значение для параметра переключателя. Чтобы указать логическое значение для параметра переключателя в значении параметра File, заключите имя и значение параметра в фигурные скобки, например: -File.\Get-Script.ps1 {-All: $ False} "

Я должен был написать это так:

PowerShell.Exe -File MyFile.ps1 {-SomeBoolParameter:False}

Поэтому в PowerShell 4.0 нет "$" перед утверждением "истина/ложь", и это сработало для меня

Ответ 5

Я думаю, лучший способ использовать/установить логическое значение как параметр для использования в вашем PS script так:

Param(
    [Parameter(Mandatory=$false)][ValidateSet("true", "false")][string]$deployApp="false"   
)

$deployAppBool = $false
switch($deployPmCmParse.ToLower()) {
    "true" { $deployAppBool = $true }
    default { $deployAppBool = $false }
}

Итак, теперь вы можете использовать его следующим образом:

.\myApp.ps1 -deployAppBool True
.\myApp.ps1 -deployAppBool TRUE
.\myApp.ps1 -deployAppBool true
.\myApp.ps1 -deployAppBool "true"
.\myApp.ps1 -deployAppBool false
#and etc...

Итак, в аргументах из cmd вы можете передать логическое значение как простую строку:).

Ответ 6

Подводя итог и дополняя существующие ответы, начиная с Windows PowerShell v5.1/PowerShell Core 7.0.0-preview.4:

Ответ дэвида Мохундро справедливо указывает, что вместо параметров [bool] следует использовать [switch] параметры в PowerShell, где наличие и отсутствие имени переключателя (-Unify указано против не указано) подразумевает его значение, что устраняет исходную проблему.


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


В PowerShell Core исходная проблема original problem (описанная в ответе Emperor XLII) была исправлена .

То есть, чтобы явно передать $true параметру [switch] с именем -Unify, вы можете написать:

pwsh -File .\RunScript.ps1 -Unify:$true  # !! ":" separates name and value, no space

Можно использовать следующие значения: $false, false, $true, true, но имейте в виду, что передача 0 или 1 не работает.

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

Note: If you declare a [TG414] parameter instead of a [TG415] (which you generally shouldn't), you must use the same syntax; even though [TG416] should work, it currently does not - see this GitHub issue.


В Windows PowerShell исходная проблема сохраняется, и, учитывая, что Windows PowerShell более не разрабатывается, вряд ли будет исправлена.

  • Обходной путь, предложенный в ответе LarsWA - даже если он основан на официальной теме справки на момент написания этой статьи - не работает в v5.1

    • Эта проблема с GitHub требует исправления документации, а также содержит команду тестирования, которая показывает неэффективность обходного пути.
  • Использование -Command вместо -File - единственный эффективный обходной путь:

:: # From cmd.exe
powershell -Command "& .\RunScript.ps1 -Unify:$true" 

С помощью -Command вы фактически передаете фрагмент кода PowerShell, который затем оценивается как обычно, и внутри PowerShell прохождение $true и $false работает (но не true и false, как сейчас). также принимается с -File).

Предостережения:

  • Использование -Command может привести к дополнительной интерпретации ваших аргументов, например, если они содержат символы $. (с -File аргументы являются литералами).

  • Использование -Command может привести к другому коду выхода.

Подробнее см. этот ответ и этот ответ.

Ответ 7

Вы также можете использовать 0 для False или 1 для True. Фактически это говорит о том, что в сообщении об ошибке:

Невозможно обработать преобразование аргументов в параметре "Унифицировать". Невозможно преобразовать значение "System.String" в тип "System.Boolean", параметры этого типа принимают только логические значения или числа, используйте $true, $false, 1 или 0.

Для получения дополнительной информации ознакомьтесь с этой статьей MSDN на Булевы значения и операторы.