Theo's helpful answer provides an effective, streamlined solution; let me add some background information:
The property values of the objects created from CSV data by Import-Csv
are invariably strings (i.e. of type [string]
).
You fundamentally cannot pass [string]
values to [bool]
or [switch]
parameters - even if those string values are 'True'
and 'False'
.
- The simplest way to convert these values to
[bool]
is [bool]::Parse($stringContainingTrueOrFalse)
(case does not matter, and the conversion works irrespective of what culture is in effect).
[bool]
parameters, which are rare, unlike the much more common [switch]
parameters (see below), accept numbers too: 0
converts to $false
, and any non-zero number to $true
.
[switch]
parameters only accept actual [bool]
values, though note that they rarely require an explicit argument, because it is their presence or absence that implies their value; e.g., -Force
is the same as -Force:$true
(note the need to follow the parameter name with :
in this case); and not specifying -Force
is (typically) the same as
-Force:$false
; there are only two scenarios in which passing an explicit argument is needed:
- To pass a switch programmatically, via a variable (e.g.,
-Force:$value
)
- To override a preference variable (e.g.
-Confirm:$false
to skip a confirmation prompt that would otherwise be shown based on the value of the $ConfirmPreference
preference variable); in this specific case passing $false
as an explicit argument does more than omitting the switch altogether would do.
Note:
The above applies to parameter binding.
By contrast, in expression contexts strings (and other objects) can be cast or coerced to [bool]
, though the behavior can be surprising:
- An empty string evaluates to
$false
, whereas any non-empty string is $true
, i.e. irrespective of its specific content.
Notably:
PS> [bool] 'False'
True # !! Evaluates to $true, because 'False' is a *non-empty* string.
In general, though, this behavior is helpful, as it allows you to use strings directly as conditionals; the following statements are equivalent:
if ($string.Length -gt 0) { 'non-empty' }
# Equivalent shorthand
if ($string) { 'non-empty' }
See the bottom section of this answer for an overview of PowerShell's implicit to-Boolean conversion across all types.
Pitfall, as of PowerShell 7.2:
While a casting a string to [bool]
works as shown above, a [bool]
variable type constraint unexpectedly behaves like a parameter declaration:
That is, while you would expect $var = [bool] 'foo'
to work the same as [bool] $var = 'foo'
(aside from the latter locking the variably type in), the latter fails:
PS> $var = [bool] 'foo' # OK: stores $true in $var
PS> [bool] $var = 'foo' # !! FAILS
... Cannot convert value "System.String" to type "System.Boolean".
Boolean parameters accept only Boolean values and numbers, such as $True, $False, 1 or 0.
This problematic asymmetry is discussed in GitHub issue #10426.