【问题标题】:Secure String Powershell安全字符串 Powershell
【发布时间】:2021-03-05 22:42:47
【问题描述】:

我在尝试将安全字符串传递给 powershell 脚本时遇到问题,但又出现此错误?

无法处理参数“密码”的参数转换。 无法将“System.String”类型的“ConvertTo-SecureString”值转换为“System.Security.SecureString”类型。

   $SecureServiceAccountPassword = ConvertTo-SecureString  "somethingstong!" -AsPlainText -Force   
    $AgentAccount = "myAccount"
    $ServiceAccountOU = "MYOU"
    POWERSHELL -COMMAND $ADAccountScript -ServiceAccountOU $ServiceAccountOU -Account $AgentAccount  -Password  $SecureAgentAccountPassword

它调用的脚本是这个。

param(
 ##MasterKey for KeePass currently stored in a DB.  
        [Parameter(Position=0,mandatory=$true)]
 [string] $ServiceAccountOU,
 ##Account to be created in AD
        [Parameter(Position=1,mandatory=$true)]
 [string] $Account,
     [Parameter(Position=2,mandatory=$true)]
 [SecureString] $Password
 )


 NEW-ADUSER -Name $Account -AccountPassword $Password -Path $SrviceAccountOU -Enabled $True -PasswordNeverExpires $True -CannotChangePassword $True


【问题讨论】:

  • 错误表明您正在传递字符串,而不是安全字符串,请执行此操作NEW-ADUSER -Name $Account -AccountPassword (ConvertTo-SecureString -AsPlainText -Force)$Password
  • 但这就是传入的内容?
  • $SecureServiceAccountPassword = ConvertTo-SecureString "somethingstong!" -AsPlainText -Force

标签: powershell


【解决方案1】:

通过 PowerShell 的 CLI 传递 [securestring] (System.Security.SecureString) 实例(Windows PowerShell 中的powershell.exe,PowerShell(核心)中的pwsh 7+),您必须传递命令才能执行 (-Command / -c)作为 script block[1]

  • 注意:虽然使用 [securestring] - 假设输入字符串不是通过 plain-text 表示获得的(如问题所示) - 无疑比使用纯文本密码更好, 在新项目中使用[securestring]不鼓励,因为它在 Unix 类平台上提供保护并且在 Windows 上只有 有限 保护。请参阅this .NET platform-compatibility recommendationthis answer

请注意,此脚本块 作为执行命令仅在您从现有 PowerShell 会话调用 时有效 - 需要通过另一个 PowerShell 实例(由 CLI 调用创建的子进程)而不是通过 直接调用(在但是,同一会话)是不寻常的。

在您的情况下,最简单的解决方案是:

powershell -c { 
  $scriptFile, $passThruArgs = $args
  & $scriptFile @passThruArgs
} -args $ADAccountScript, $ServiceAccountOU, $AgentAccount, $SecureServiceAccountPassword

请注意,这依赖于位置参数传递。

如果你想使用 named 参数,就像你自己的尝试一样,你必须求助于基于哈希表的splatting

# Create the hashtable whose entries map onto the target
# script's parameters.
$htArgs = @{
    ServiceAccountOU = 'foo'
    Account          = 'bar'
    Password         = ConvertTo-SecureString  "somethingstrong!" -AsPlainText -Force
}

powershell -c { 
  $scriptFile, $passThruArgs = $args
  & $scriptFile @passThruArgs
} -args $ADAccountScript, $htArgs

[1] 如果您将 -Command / -c 参数作为字符串传递 - 这是从外部调用 PowerShell 的 CLI 时的唯一选择 PowerShell - [securestring] 被传递作为它的字符串表示,这是它的完整类型名称,逐字逐句'System.Security.SecureString';也就是说,实际的“安全”内容丢失了
相比之下,传递 脚本块 会在后台触发基于 CLIXML 的序列化,其中支持传递和接收 对象 而不是 仅文本 - 请参阅this answer 了解更多信息。

【讨论】:

    【解决方案2】:

    您的密码没有作为安全字符串传递给 PS。所以,你必须转换它并传递它。

    替换这个:

    NEW-ADUSER -Name $Account -AccountPassword $Password -Path $SrviceAccountOU -Enabled $True -PasswordNeverExpires $True -CannotChangePassword $True
    

    到:

    NEW-ADUSER -Name $Account -AccountPassword (ConvertTo-SecureString "$password" -AsPlainText -Force) -Path $SrviceAccountOU -Enabled $True -PasswordNeverExpires $True -CannotChangePassword $True
    

    最好的方法是直接传递凭证:

    $User = "MyUserName"
    $File = "C:\Temp 2\Password.txt"
    $password = Get-Content "C:\Passwords\password.txt" | ConvertTo-SecureString 
    $credential = New-Object System.Management.Automation.PsCredential("Luke",$password)
    $MyCredential=New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $User, (Get-Content $File | ConvertTo-SecureString)
    
    New-ADUser -credential $MyCredential # Followed by whatever you need except the username and password.
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-03
      • 2015-08-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多