代码之家  ›  专栏  ›  技术社区  ›  binki

如何让ReadLineAsSecureString()接受管道输入?

  •  1
  • binki  · 技术社区  · 7 年前

    当我使用 cmd 然后用管道输送到 powershell ReadLine()

    C:\Users\ohnob>ECHO hi|powershell -Command "write-host $host.UI.ReadLine()"
    hi
    hi
    

    但是,当我使用 命令 和管道 动力壳 ReadLineAsSecureString() ,它将一直挂起,直到我在终端中键入return:

    C:\Users\ohnob>ECHO hi|powershell -Command "write-host $host.UI.ReadLineAsSecureString()"
    

    当会话是交互式的时,我需要以安全字符串(使用星号)的形式读取。但当有管道输入时,我需要读取管道输入。我怎样才能做到这一点 动力壳 读线() 而不是 ReadLineAsSexcureString() ,但我不知道如何在powershell中获得标准输入的句柄,我只能访问这个 PSHostUserInterface 对象。

    编辑:为了澄清,当我使用 ReadLineAsSecureString() 读线() 一行

    1 回复  |  直到 7 年前
        1
  •  1
  •   mklement0    7 年前

    Jeroen Mostert 在评论中提出了一些好的观点,特别是 $host.UI.ReadLineAsSecureString() / Read-Host -AsSecureString 大概吧 按设计 出于安全原因,不接受管道输入 .

    因此,必须明确区分接收管道输入和不接收任何输入:

    • PowerShell提供通过自动 $Input 变量。

    • $MyInvocation.ExpectingInput

    如果有管道输入,则传递其 第一行 ConvertTo-SecureString
    如果没有,打电话 读取主机-AsSecureString :

    $secStr = if ($MyInvocation.ExpectingInput) {
        # Alternatively, use $firstLine = [console]::ReadLine() - thanks, @binki
        $firstLine = $($null = $Input.MoveNext(); $Input.Current)
        ConvertTo-SecureString -AsPlainText -Force $firstLine
      } else {
        Read-Host -AsSecureString -Prompt 'Enter secret'
      }
    

    作为从中调用的命令行 cmd.exe 它还输出结果:

    C:>echo hi| powershell -Command "$secStr = if ($MyInvocation.ExpectingInput) { $firstLine = $($null = $Input.MoveNext(); $Input.Current); ConvertTo-SecureString -AsPlainText -Force $firstLine } else { Read-Host -AsSecureString -Prompt 'Enter secret' }l$secStr"
    

    但是,请注意,通过设计来保护字符串的 System.Security.SecureString ,所以你只能看到这些。


    [1] 我很抱歉 管道 读取主机-AsSecureString 更大的潜力 MyCustomEcho.exe secret | ...
    ConvertTo-SecureString -AsPlainText 总是一种选择 额外的 需要通过吗 -Force 还指示PowerShell考虑使用非交互式键入的纯文本输入。

    [2] 自动的 $输入 变量是 (type)从stdin枚举行 按需 . 索引 访问,例如 $Input[0] .MoveFirst() 启动枚举,然后访问 .Current $输入 生成剩余的行。
    唯一的原因 $(...) 围绕 $null = $Input.MoveNext(); $Input.Current 所以这两个语句可以用 为概念清楚起见,返回第一行的语句;使用 $null = $Input.MoveNext() $firstLine = $Input.Current

    推荐文章