Как передать логические значения в 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?
Ответы
Ответ 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 на Булевы значения и операторы.