事实证明,您的意图是抑制将通过标准输入提供的命令回显到 PowerShell CLI(powershell.exe for Windows PowerShell,pwsh for PowerShell (Core) 7+):
为此,使用-Command - (-c -),它 - like -File -(-f -,默认行为) - 接受(独立) 命令通过标准输入一一对应,但是 - 不像 -File - - 既不打印提示字符串也不回显提供的命令:
# OK: Just the piped command's *output* prints.
PS> 'Get-Date' | powershell.exe -Command -
Friday, September 3, 2021 10:08:07 AM
# Pseudo-interactive behavior:
# The piped command's output is:
# * *preceded by* the prompt string as well as the input command.
# * *followed by* another rendering of the prompt string.
PS> 'Get-Date' | powershell.exe -File -
PS C:\Users\jdoe> Get-Date
Friday, September 3, 2021 10:09:44 AM
PS C:\Users\jdoe>
注意:在上面的示例中,single 命令是通过 stdin(通过管道)提供的,并且由于不再提供 stdin 输入,因此 PowerShell 进程退出。但是,在您保持标准输入打开的情况下,您将能够无限期地向 PowerShell 进程逐一提供命令。
警告:两者 -File - 和 -Command - 都表现出有问题的伪交互行为;值得注意的是,跨越多行的命令必须以 two 换行符结束;详情请见GitHub issue #3223。
注意:
-
提供都不提供 -Command - 和 -File - 与 -File - 基本相同,只是在启动时也会打印版权信息(可以用 -NoLogo 单独抑制);简而言之:... | powershell -NoLogo 等同于
... | powershell -File -
-
为提供可预测的执行环境并避免额外开销,请考虑在 -File / -Command 前面加上 -NoProfile,这样可以绕过加载 PowerShell 的 profile files。
-
至于 一般 stty -echo 等效项(POSIX-mandated stty 实用程序在类 Unix 平台上可用,在 Windows 上不可用):
- 此命令在 终端 上运行,而不是在其中运行的 shell。
- 类似
bash 的 POSIX 兼容 shell不会在发出此命令后尝试将终端重置为之前的状态,因此用户输入的输入在会话或直到终端重置。
- 相比之下,PowerShell(在类 Unix 平台上运行的跨平台 v7+ 版本)确实在运行每个命令后重置终端,因此运行
stty -echo 实际上是不-op。
- 换句话说:您无法在任何平台上(至少从 PowerShell 7.2 开始)在 PowerShell 中实现相同的效果
在一个松散相关的注释上(由对问题意图的误读提示),以下讨论:
如何隐藏或屏蔽通过 Read-Host cmdlet 请求的交互式用户输入:
没有内置的 PowerShell 功能(从 v7.2 开始)隐藏用户键入的内容,但 如果意图只是 屏蔽用户输入,为了隐藏正在输入的敏感信息,例如密码,您有两个选项 - 两者都屏蔽每个输入的字符打印*:
使用Read-Host -AsSecureString:
$$valueEnteredSecure = Read-Host -AsSecureString -Prompt 'Enter your password'
请注意,这会输出一个 System.Security.SecureString 实例(在 Windows 上提供有限的安全性,而在类 Unix 平台上几乎没有),您可以将其转换回常规字符串,如下所示:
$valueEntered = [System.Net.NetworkCredential]::new('', $valueEnteredSecure).Password
在 PowerShell (Core) 7.0+ 中,您可以选择使用(尽管请注意下面更简单的 7.1+ 解决方案):
$valueEntered = ConvertFrom-SecureString $valueEnteredSecure -AsPlainText
PowerShell (Core) 7.1+ 现在支持显示相同 UI 行为的 -MaskInput 参数,但直接返回常规字符串 :
# PowerShell 7.1+
$valueEntered = Read-Host -MaskInput -Prompt 'Enter your password'
如果真正抑制用户键入的所有字符的显示是必须的,那么您必须创建一个在循环中使用$host.ui.RawUI.ReadKey('NoEcho') 的自定义解决方案:
这是一个简单的实现,您可以将其称为
$valueEntered = Read-HostSilent -Prompt 'Enter your password',例如:
function Read-HostSilent {
param([string] $Prompt)
if ($Prompt) { Write-Host -NoNewline "${Prompt}: " }
$entered = $null; $done = $false
do {
$key = $host.ui.RawUI.ReadKey('NoEcho')
switch ($key.VirtualKeyCode) {
# Backspace
8 { if ($entered.Length -gt 1) { $entered = $entered.Substring(0, $entered.Length-1) } }
# Enter
13 { $done = $true; break }
default {
if ($key.Character) { # printable?
$entered += $key.Character
}
}
}
} while (-not $done)
$entered # output
}