Обычно, если вы хотите отложить спецификацию параметра switch на некоторую переменную, вы можете передать выражение в параметр switch, как в случае с параметром WhatIf.
test.ps1
param ( [string] $source, [string] $dest, [switch] $test )
Copy-Item -Path $source -Destination $dest -WhatIf:$test
Это обеспечивает большую гибкость при работе с переключателями. Однако когда вы вызываете powershell с помощью cmd.exe или чего-то подобного, получается что-то вроде этого:
D:\test>powershell -file test.ps1 -source test.ps1 -dest test.copy.ps1 -test:$true
D:\test\test.ps1 : Cannot process argument transformation on
parameter 'test'. Cannot convert value "System.String" to type "System.Manageme
nt.Automation.SwitchParameter", parameters of this type only accept booleans or
numbers, use $true, $false, 1 or 0 instead.
At line:0 char:1
+ <<<<
+ CategoryInfo : InvalidData: (:) [test.ps1], ParentContainsError
RecordException
+ FullyQualifiedErrorId : ParameterArgumentTransformationError,test.ps1
Однако тот же результат появляется при передаче -test:true
и -test:1
. Почему это не работает? Разве система преобразования типов Powershell не должна автоматически распознавать эти строки как конвертируемые в bool или switch и преобразовывать их?
Означает ли это, что при вызове сценариев powershell из какой-либо другой системы (например, системы сборки) необходимо создавать сложные структуры управления потоком, чтобы определить, включать или нет переключатель в командную строку или опустить его? Это кажется утомительным и чреватым ошибками, что наводит меня на мысль, что это не так.
Используйте свойство IsPresent коммутатора. Пример:
function test-switch{
param([switch]$test)
function inner{
param([switch]$inner_test)
write-host $inner_test
}
inner -inner_test:$test.IsPresent
}
test-switch -test:$true
test-switch -test
test-switch -test:$false
True
True
False
BTW, я использовал функции, а не скрипт, чтобы было проще тестировать.