无法将String转换为安全字符串以在New-ADUser中使用

时间:2013-10-04 18:56:20

标签: powershell powershell-v2.0 powershell-v3.0

我正在使用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字段输出不正确。为Name =输入“$ lname,$ fname”时由于某种原因导致$ lname的完整输出。我创建了一个名为$ name的新字符串,并将其设置为= $ lname.text +“,”+ $ fname.text。

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

2 个答案:

答案 0 :(得分:16)

更改

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

答案 1 :(得分:0)

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

public class ClientScope
{
     public int Id { get; set; }
     public string Scope { get;set; }
     .....
}

在终端和PowerShell中。

Benjamin's Code

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

public class StringToScopesConvert : ITypeConverter<string, ClientScope>
{
    public ClientScope Convert(string source, ClientScope destination, ResolutionContext context)
    {
        if (source.Equals(destination.Scope))
            return destination;

        return new ClientScope
        {
            Scope = source
        };
    }
}

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

CreateMap<ClientDto, Client>()
CreateMap<string, ClientScope>().ConvertUsing<StringToScopesConvert>();

My similar code (and the error)

要解决此问题,我需要使用假定为本地脚本变量而不是环境变量的变量:

_mapper.Map(clientDto, client);

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

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

Working with local variables

为了将来参考,我正在使用Powershell 5.1.19041.1。我知道他们正在使用PS改变相当大的功能,因此将来可能会改变。对于我而言,这可能是最好的!