19

我正在使用 Primal Forms Community Edition 创建一个 GUI,它将简化我们的秘书的新学生创建过程。在较低级别的学校,学生使用他们的生日作为他们的密码,所以他们很容易记住。

我有一个标记为“生日”字段的文本输入框。我要做的是获取该字段并将其用于 New-ADUser 中的 -AccountPassword。但是,无论我尝试什么,在尝试使用我的脚本创建新用户时总是会收到此错误。

New-ADUser : Cannot bind parameter 'AccountPassword'. Cannot convert the "System.Security.SecureString" value of type 
"System.String" to type "System.Security.SecureString".
At C:\Users\pomeroyt\Google Drive\Work\Scripts\Powershell\student_creation_gui.ps1:377 char:12
+ New-ADUser @User
+            ~~~~~
    + CategoryInfo          : InvalidArgument: (:) [New-ADUser], ParameterBindingException
    + FullyQualifiedErrorId : CannotConvertArgumentNoMessage,Microsoft.ActiveDirectory.Management.Commands.NewADUser

我正在使用的代码如下所示。

$password = $dob.text | ConvertTo-SecureString -AsPlainText -Force
$user = @{
    Description = "Student"
    UserPrincipalName = "$username@domain.local"
    Name = "$lname.text, $fname.text"
    SamAccountName = "$username"
    Surname = "$lname.text" 
    GivenName = "$fname.text" 
    EmailAddress = "$email" 
    HomeDrive = H: 
    HomeDirectory = "\\$server\Students\$yog\$username" 
    ScriptPath = "$script" 
    ChangePasswordAtLogon = 0 
    CannotChangePassword = 1 
    PasswordNeverExpires = 1 
    AccountPassword = "$password"
    Enabled = 1
    Path = "OU=$yog,OU=$group,OU=STUDENTS,DC=domain,DC=local"
    }
New-ADUser @User

我真的很茫然,因为我所看到的一切都表明我正在做的事情应该有效

编辑 -

下面的解决方案确实解决了密码问题。但是,我没有意识到我实际上看到了我的代码的其他问题。

我打开 -verbose 来查看发生了什么,发现 Name 字段没有正确输出。将 "$lname, $fname" 放入 Name = 时,由于某种原因导致 $lname 的完整输出。我创建了一个名为 $name 的新字符串并将其设置为 = $lname.text+", "+$fname.text。

现在 Name = $name 并且命令按预期触发。

4

2 回答 2

26

改变

AccountPassword = "$password"

AccountPassword = $password

如果变量周围有引号,则将其视为常规字符串而不是安全字符串。证明:

$plainText = "Plain text"
$secureString = ConvertTo-SecureString $plainText -AsPlainText -Force
$quotedSecureString = "$secureString"
$plainText.GetType()
$secureString.GetType()
$quotedSecureString.GetType()

结果是

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     String                                   System.Object
True     False    SecureString                             System.Object
True     True     String                                   System.Object
于 2013-10-04T19:43:23.170 回答
0

我遇到了与 OP 相同的问题,其中安全字符串将被解析为字符串。本杰明的反应似乎很可靠,所以我通过运行对其进行了测试:

$plainText = "Plain text"
$secureString = ConvertTo-SecureString $plainText -AsPlainText -Force
$quotedSecureString = "$secureString"
$plainText.GetType()
$secureString.GetType()
$quotedSecureString.GetType()

在终端和 PowerShell 中。

本杰明密码

但是,我的尝试包含一个环境变量(我正在构建一个 docker 容器),它似乎反应不同。

$env:SVCUSER="testuser"
$env:SVCPASS="testpass"
$env:SITENAME="test.com"
$env:SecurePass=ConvertTo-SecureString $env:SVCPASS -AsPlainText -Force
New-LocalUser -Name "$env:SVCUSER" -Password $env:SecurePass -Description "$env:SITENAME Site User"

这会导致与 OP 相同的错误。

Cannot bind parameter 'Password'. Cannot convert the "System.Security.SecureString" value of type "System.String" to type "System.Security.SecureString".

我的类似代码(和错误)

为了解决这个问题,我需要使用我认为是本地脚本变量而不是环境变量:

$env:SVCUSER="testuser"
$env:SVCPASS="testpass"
$env:SITENAME="test.com"
$SecurePass=ConvertTo-SecureString $env:SVCPASS -AsPlainText -Force
New-LocalUser -Name "$env:SVCUSER" -Password $SecurePass -Description "$env:SITENAME Site User"

我认为这是有道理的,因为作为环境变量编写意味着(尽管是安全的)字符串存在,直到这些变量被重置。

当我分析第一种和第二种方法的输出类型(即本地和环境变量)时,我可以看到两者具有不同的类型,正如错误所暗示的那样:

使用局部变量

为了将来参考,我使用的是 Powershell 5.1.19041.1。我知道他们正在用 PS 改变相当大的功能,所以将来可能会改变。在我的情况下,这可能是最好的!

于 2020-09-16T09:48:11.053 回答