如何自动运行提示UI选择的PowerShell脚本?

时间:2014-01-25 21:09:16

标签: powershell scripting

我有一个看起来像这样的powershell脚本p1.ps1(不完全是,但这可以作为一个例子):

$yes = New-Object System.Management.Automation.Host.ChoiceDescription "&Yes", "Do the action."
$no = New-Object System.Management.Automation.Host.ChoiceDescription "&No", "Exit."
$options = [System.Management.Automation.Host.ChoiceDescription[]]($yes, $no)
$result = $host.ui.PromptForChoice($title, $message, $options, 1)

如何编写另一个脚本p2.ps1,它将运行第一个脚本(p1.ps1)并为其提供答案,以便p2.ps1在没有问题的情况下执行?

我试过了:

echo y | p1.ps1

但它没有成功。

2 个答案:

答案 0 :(得分:9)

$host.ui.PromptForChoice()正在与主机交互,而不是与管道的输出流交互。我不知道一种自动化主机提示的方法。

更清洁的解决方案是将-Force切换添加到p1.ps1

[CmdletBinding()]
Param(
  [switch]$Force = $false
)

并使该开关覆盖提示:

if (-not $Force) {
  $yes = New-Object System.Management.Automation.Host.ChoiceDescription ...
  $no  = New-Object System.Management.Automation.Host.ChoiceDescription ...
  $options = [System.Management.Automation.Host.ChoiceDescription[]]($yes, $no)
  $result = $host.ui.PromptForChoice($title, $message, $options, 1)
} else {
  $result = 0
}

这样,当您运行如下脚本时,将不会显示提示:

./p1.ps1 -Force

答案 1 :(得分:1)

根据您生成脚本的方式,powershell sendkeys可以解决问题。

[void][System.Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms')
[System.Windows.Forms.SendKeys]::SendWait("Y")
[System.Windows.Forms.SendKeys]::SendWait("{ENTER}")

警告说,如果脚本被隐藏运行它将无法工作,因为我们无法将密钥发送到隐形窗口。当我们发送“Y + ENTER”命令时,如果它还没有焦点,我们可能需要在第一个脚本窗口中添加一行或两个Focus设置。