【问题标题】:Powershell import csv with $true and $falsePowershell 使用 $true 和 $false 导入 csv
【发布时间】:2021-10-27 23:09:57
【问题描述】:

我正在尝试学习如何在 Powershell 中导入 csv 并从中创建用户。 我需要导入的值之一需要转换为布尔值。这些值只会是$truefalse

我当前的代码是

param([Parameter(Mandatory)][string] $inputfile)

$ADUsers = Import-csv $inputfile -Delimiter ';'

foreach ($User in $ADUsers) {
    $Name = $User.Name
    $SurName = $User.sn
    $GivenName = $User.Givenname
    $Email = $User.Email
    $SamAccountName = $User.samAccount
    $Path = $User.ParentOU
    $Password = $User.Password
    $Enabled = [System.Convert]::ToBoolean($User.Enabled)
    $ChangePasswordAtLogon = [System.Convert]::ToBoolean($User.mustChangePassword)
    $Description = $User.Description
    
    New-ADUser `
        -Name = $Name `
        -Surname =  $SurName `
        -GivenName = $GivenName `
        -EmailAddress = $Email `
        -SamAccountName = $SamAccountName `
        -Path = $Path `
        -AccountPassword (ConvertTo-SecureString $Password -AsPlainText -Force) `
        -Enabled = $Enabled `
        -ChangePasswordAtLogon = $ChangePasswordAtLogon `
        -Description = $Description
}

使用当前代码,我唯一的问题(目前)似乎是我无法将此字符串解析为布尔值。错误: Exception calling "ToBoolean" with "1" argument(s): "String was not recognized as a valid Boolean."

谁知道解决这个问题的最佳方法?

【问题讨论】:

  • 这些字段在 csv 中的值是什么?
  • 这些值是 csv 本身中的 $true$false

标签: powershell type-conversion import-csv


【解决方案1】:

如果 CSV 包含 EnabledChangePasswordAtLogon 的字符串值,字面意思是 '$true''$false',您需要从中删除美元符号才能将它们转换为真正的布尔值。

另外,我建议使用SplattingNew-ADUser 的参数,这样您就可以摆脱所有不需要的额外变量,尤其是那些讨厌的反引号:

param([Parameter(Mandatory)][string] $inputfile)

$ADUsers = Import-Csv -Path $inputfile -Delimiter ';'

foreach ($User in $ADUsers) {
    $userParams = @{
        Name                  = $User.Name
        Surname               = $User.sn
        GivenName             = $User.Givenname
        EmailAddress          = $User.Email
        SamAccountName        = $User.samAccount
        Path                  = $User.ParentOU
        AccountPassword       = (ConvertTo-SecureString $User.Password -AsPlainText -Force)
        Description           = $User.Description
        # if these values in the CSV are '$true' or '$false' literally, remove the dollar sign
        Enabled               = [System.Convert]::ToBoolean($User.Enabled -replace '\$')
        ChangePasswordAtLogon = [System.Convert]::ToBoolean($User.mustChangePassword -replace '\$')
    }

    New-ADUser @userParams
}

【讨论】:

  • 干得好; [bool]::Parse() 是一个更简洁的替代方案。
【解决方案2】:

Theo's helpful answer 提供了一个有效的、简化的解决方案;让我补充一些背景信息

  • Import-Csv 从 CSV 数据创建的对象的属性值总是字符串(即[string] 类型)。

  • 基本上不能将[string] 值传递给[bool][switch] 参数 - 即使这些字符串值是'True''False'

    • 将这些值转换为[bool] 的最简单方法是[bool]::Parse($stringContainingTrueOrFalse)(不区分大小写,无论有效的文化是什么,转换都有效)。
  • [bool] 参数,与更常见的[switch] 参数不同(见下文),也接受数字0 转换为 $false,任何非零数转换为 $true

  • [switch] parameters 只接受实际的[bool],但请注意它们很少需要显式参数,因为这是它们的存在或不存在,这意味着它们的价值;例如,-Force-Force:$true 相同(注意在这种情况下需要在参数名称后面加上:); not 指定-Force (通常)与
    -Force:$false 相同;只有两种情况需要传递显式参数:

    • 通过变量以编程方式传递开关(例如,-Force:$value
    • 覆盖首选项变量(例如,-Confirm:$false 跳过确认提示,否则将根据 $ConfirmPreference 首选项变量的值显示);在这种特定情况下,将$false 作为显式参数传递更多,而不是完全省略开关。

注意:

上述适用于参数绑定
相比之下,表达式上下文中,字符串(和其他对象)可以被强制转换或强制为[bool],尽管行为可以大吃一惊

  • 字符串的计算结果为$false,而any非空字符串 是$true,即与其具体内容无关

值得注意的是:

PS> [bool] 'False'
True # !! Evaluates to $true, because 'False' is a *non-empty* string.

不过,一般来说,这种行为是有帮助的,因为它允许您直接使用字符串作为条件;以下语句是等价的:

if ($string.Length -gt 0) { 'non-empty' }

# Equivalent shorthand
if ($string) { 'non-empty' }

请参阅this answer 的底部,了解PowerShell 在所有类型中的隐式到布尔转换的概述


陷阱,从 PowerShell 7.2 开始:

虽然将字符串强制转换[bool] 的工作方式如上所示,但[bool] 变量类型约束 出乎意料地表现得像参数声明

也就是说,虽然您希望 $var = [bool] 'foo'[bool] $var = 'foo' 的工作方式相同(除了后者锁定变量类型),但后者失败

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.

GitHub issue #10426 讨论了这种有问题的不对称性。

【讨论】:

  • 阅读链接中讨论的问题。很高兴看到一位真正的 PowerShell 创建者评论 (Bruce) 很有趣,而且确实令人困惑(*关于布尔问题)。
猜你喜欢
  • 2017-09-26
  • 1970-01-01
  • 2018-05-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-11
相关资源
最近更新 更多