Powershell 使用 $true 和 $false 导入 csv
Powershell import csv with $true and $false
我正在尝试学习如何在 Powershell 中导入 csv 并从中创建用户。
我需要导入的值之一需要转换为布尔值。这些值只会是 $true
或 false
.
我当前的密码是
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 包含 Enabled
和 ChangePasswordAtLogon
的字面意思为 '$true'
或 '$false'
的字符串值,您需要从中删除美元符号才能将它们转换成真正的布尔值。
此外,我建议使用 Splatting New-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
}
提供了一个有效的、简化的解决方案;让我添加一些背景信息:
Import-Csv
从 CSV 数据创建的对象的 属性 值总是 strings(即类型 [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
,而任何非空字符串是$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' }
请参阅 的底部部分以了解 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 中导入 csv 并从中创建用户。
我需要导入的值之一需要转换为布尔值。这些值只会是 $true
或 false
.
我当前的密码是
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 包含 Enabled
和 ChangePasswordAtLogon
的字面意思为 '$true'
或 '$false'
的字符串值,您需要从中删除美元符号才能将它们转换成真正的布尔值。
此外,我建议使用 Splatting New-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
}
Import-Csv
从 CSV 数据创建的对象的 属性 值总是 strings(即类型[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
,而任何非空字符串是$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' }
请参阅
陷阱,从 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 中讨论了这种有问题的不对称性。