从另一个 PS1 调用 PowerShell 脚本 PS1,然后自动执行用户输入



我有两个脚本:

脚本 1和脚本2

脚本 1包含:

$Title = "bullshit"
$host.UI.RawUI.WindowTitle = $Title    
$Name = Read-Host -Prompt 'Input your  name'
Write-Host "Your name is '$Name'" 

脚本 2包含:

./Script1.ps1

我需要的是运行 Script2,它将运行 Script1,一旦该脚本要求用户输入,Script2 只需按回车键,让它继续。

我尝试了这里提到的解决方案,但它不起作用 - 它一直在等待用户输入,只有在您手动按 Enter 后,它才会产生按键(输入)。

我发现的其他 Script2 建议解决方案与上述解决方案具有相同的问题:

./Script1.ps1
$wshell = New-Object -ComObject wscript.shell;
$wshell.AppActivate('bullshit')
Sleep 2
$wshell.SendKeys('myPassword{ENTER}')

你知道我做错了什么吗? 一旦脚本 1 要求,如何使脚本 2 按回车键?

您的问题的直接答案是,您需要在./Script1.ps1调用并行运行击键发送代码,因为./Script.ps1是一个同步调用,其Read-Host调用会阻止进一步处理,直到提供响应。

但是,正如 kconsiglio 所指出的那样,在您的简单情况下,只需提前发送击键就足够了,依靠它们进行缓冲并稍后由Read-Host读取,这不需要并行性:

# Send the keystrokes and rely on their getting buffered, 
# so that the subsequently launched ./Script.ps1 reads them.
(New-Object -ComObject Wscript.Shell).SendKeys('myPassword{ENTER}')  
./Script.ps1

您可能需要并行性才能与交互式脚本进行更复杂的交互,在这种情况下,您可以使用Start-Job或最好是Start-ThreadJob(默认情况下PowerShell (Core) 7+中可用,可在Windows PowerShell按需安装)进行以下并行执行:

$Title = "bullshit"
$host.UI.RawUI.WindowTitle = $Title    
# Launch the keystroke-sending code in parallel, in the background.
# Note: If Start-ThreadJob is available / installed, use it instead.
$jb = Start-Job {
$wshell = New-Object -ComObject wscript.shell;
$wshell.AppActivate('bullshit')
Sleep 1
$wshell.SendKeys('myPassword{ENTER}')  
}
$Name = Read-Host -Prompt 'Input your  name'
Write-Host "Your name is '$Name'" 
Remove-Job -Force $jb

但是,发送击键总是很脆弱(可能会中断),并不总是一种选择(例如,在隐藏的计划任务中),如果有强大的替代方案,最好避免

您可以通过以下两种方式之一自动输入到Read-Host

  • 通过PowerShell CLI调用目标脚本,在这种情况下,可以通过管道 (stdin) 提供Read-Host响应 - 值得注意的是,这在会话中不起作用

    # Note: Use 'pwsh.exe' if you're running PowerShell (Core) 7+
    'myPassword' | powershell.exe -File ./Script.ps1
    
    • 潜在的缺点(除了由于启动另一个 PowerShell 实例而导致的性能下降)是./Script.ps1输出将仅是文本
  • 定义一个代理Read-Host函数,该函数替代内置 cmdlet 并自动返回所需的字符串,而不是提示:

    function Read-Host { 'mypassword' }
    ./Script.ps1
    Remove-Item function:Read-Host
    
    • 技术是从此答案中借用的,该答案还显示了如何根据提示字符串使自动响应成为条件。

    • 优点是进程内执行,在脚本的输出中保留类型保真度

    • 请注意,您只需要返回实际所需的响应,例如'mypassword'- 这里涉及击键的模拟,因此不需要诸如{ENTER}之类的关键说明符(只有.SendKeys()方法才能理解)。

相关内容

  • 没有找到相关文章

最新更新