仅在非交互式运行时如何从 Powershell 脚本返回退出代码

Posted

技术标签:

【中文标题】仅在非交互式运行时如何从 Powershell 脚本返回退出代码【英文标题】:How to return an exit code from a Powershell script only when run non-interactively 【发布时间】:2010-12-08 19:41:51 【问题描述】:

我有很多脚本作为计划任务运行。所以他们会在任何失败时执行$host.setshouldexit(1),这会在任务调度程序中显示为返回码。

我还希望能够在调试和测试时以交互方式运行这些脚本。所以$host.setshouldexit() 会终止我的 powershell 或 ISE 会话。

我的问题是:如何检测脚本是否以非交互方式运行?如果是,那么我将使用setshouldexit,否则它将打印错误代码或非破坏性的东西。 (请注意,我不想使用[environment]::userinteractive,因为这些脚本并不总是在操作系统认为的非交互式会话中运行。)

有一个 -noninteractive 开关用于计划任务。有什么方法可以从 powershell 查询吗?

【问题讨论】:

【参考方案1】:

$Host.SetShouldExit 方法应该不是必需的,并且实际上是不一致的,这取决于您调用脚本的方式。使用关键字 exit 应该可以让您获得退出状态。

使用powershell -F script.ps1

exit - 有效 SetShouldExit - 忽略

使用powershell -c '.\script.ps1'

exit - 状态减少到 0 或 1,分别代表脚本的成功或失败。 SetShouldExit - 以正确状态退出,但脚本中的剩余行仍在运行。

使用powershell -c '.\script.ps1; exit $LASTEXITCODE' [1]:

exit - 有效 SetShouldExit - 以状态 == 0 退出,脚本中的剩余行仍在运行。

直接从 powershell 调用 (> .\script.ps1):

exit - 有效 SetShouldExit - 终止调用具有给定退出状态的 powershell 主机

【讨论】:

【参考方案2】:

为什么不让它接受一个参数“testing”来设置测试期间的正确行为?你有一个历史缓冲区,所以它几乎不需要再输入了。

【讨论】:

嗯,还不错。我会接受的。【参考方案3】:

我有同样的问题。以下对我有用:

# Exit with Return Code when NOT using PowerShell ISE
if ($psise -eq $Null)

    $host.SetShouldExit(1)

【讨论】:

交互式 shell 比 ISE 多。【参考方案4】:

在找到您的问题后,我进一步解决了这个问题并找到了$MyInvocation.MyCommand.Name。这在命令解释器和 ISE 命令解释器中都是 False。当一个脚本(我的是jest.ps1)只包含以下行时:Write-Host $MyInvocation.MyCommand.Name 从 cmd.exe 调用 powershell.exe 运行为:

%SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe  -ExecutionPolicy RemoteSigned -NoExit -NonInteractive -NoProfile -File "M:\WindowsPowerShell\Jest.ps1"

输出很简单:

Jest.ps1

【讨论】:

还有,顺便说一句,谢谢你使用 $host.SetShouldExit(1) 的例子! 内联代码用反引号(`)标记,代码块通过每行缩进4个空格来标记。请参阅Editing FAQ。【参考方案5】:

检查 $Host.Name。如果您的脚本在 IDE 之外运行,它将返回值 ConsoleHost。否则它将返回对 IDE 的引用,例如 Windows PowerShell ISE HostPowerGUIScriptEditorHost

我必须使用SetShouldExit,因为运行我的脚本的调度程序通常会忽略其他指示失败的方法。当$Host.NameConsoleHost 时,我添加了一个函数以允许SetShouldExit。它在测试过程中节省了大量的 IDE 崩溃。

【讨论】:

当脚本作为作业运行时,$Host.Name 等于“ServerRemoteHost”(在 PS v5 上测试)。【参考方案6】:

这直接回答了发布者关于是否可以查询powershell控制台是否使用-NonInteractive开关启动的问题。

Function Test-IsPowerShellConsoleNonInteractive  [Boolean]([Environment]::GetCommandLineArgs() -Match '-NonInteractive') 
$IsPSConsoleNonInteractive = Test-IsPowerShellConsoleNonInteractive
If ($IsPSConsoleNonInteractive)  $Host.SetShouldExit(2) 

【讨论】:

以上是关于仅在非交互式运行时如何从 Powershell 脚本返回退出代码的主要内容,如果未能解决你的问题,请参考以下文章

本地化应用程序仅在非基本语言上崩溃,并且仅在未使用Xcode运行时崩溃

我的 PowerShell 脚本仅在从 ISE 运行时才有效

OctoberCMS - 如何使可折叠列表默认仅在非移动设备上处于活动状态

脚本无法在非活动选项卡上运行

maven release-plugin 在非交互模式下的使用

如何在不同的运行空间中运行函数,PowerShell