I have a lot of scripts that are running as scheduled tasks. So they do a $host.setshouldexit(1)
on any failure, which shows up in the task scheduler as the return code.
I also want to be able to run these scripts interactively while debugging and testing. So the $host.setshouldexit()
开发者_开发百科 kills my powershell or ISE session.
My question is: how can I detect if a script is running non-interactively? If it is, then I'll use setshouldexit
, otherwise it will print the error code or something nondestructive. (Note that I don't want to use [environment]::userinteractive
because these scripts are not always running in what the OS thinks is a non-interactive session.)
There is a -noninteractive switch that I'm using for the scheduled tasks. Is there some way I can query that from powershell?
The $Host.SetShouldExit
method should not be necessary, and is actually inconsistent, depending on how you are calling your scripts. Using the keyword exit
should get you your exit status.
Using powershell -F script.ps1
:
exit
- worksSetShouldExit
- ignored
Using powershell -c '.\script.ps1'
:
exit
- status reduced to 0 or 1, for success or failure of the script, respectively.SetShouldExit
- exits with correct status, but remaining lines in script are still run.
Using powershell -c '.\script.ps1; exit $LASTEXITCODE'
[1]:
exit
- worksSetShouldExit
- exits with status == 0, and remaining lines in script are still run.
Calling directly from powershell (> .\script.ps1
):
exit
- worksSetShouldExit
- terminates calling powershell host with given exit status
Why not just have it take a parameter "testing" which sets the right behavior during your tests? You have a history buffer so it will be hardly any more typing to run.
I had the same issue. The following works for me:
# Exit with Return Code when NOT using PowerShell ISE
if ($psise -eq $Null)
{
$host.SetShouldExit(1)
}
Upon finding your question I have taken the issue a bit further and found $MyInvocation.MyCommand.Name
. This is False in both the command interpreter and the ISE command interpreter. And when a script (mine is jest.ps1
) containing just the line: Write-Host $MyInvocation.MyCommand.Name
is run from cmd.exe call to powershell.exe as:
%SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy RemoteSigned -NoExit -NonInteractive -NoProfile -File "M:\WindowsPowerShell\Jest.ps1"
Output is simply:
Jest.ps1
Check $Host.Name. If your script is running outside of an IDE, it will return a value of ConsoleHost
. Otherwise it will return a reference to the IDE such as Windows PowerShell ISE Host
or PowerGUIScriptEditorHost
.
I have to use SetShouldExit
because the scheduler that runs my scripts usually ignores other methods of indicating a failure. I add a function to allow SetShouldExit
when $Host.Name
is ConsoleHost
. It saves a lot of IDE crashes during testing.
This directly answers the question poster had about whether or not you can query if the powershell console was launched with -NonInteractive switch.
Function Test-IsPowerShellConsoleNonInteractive { [Boolean]([Environment]::GetCommandLineArgs() -Match '-NonInteractive') }
$IsPSConsoleNonInteractive = Test-IsPowerShellConsoleNonInteractive
If ($IsPSConsoleNonInteractive) { $Host.SetShouldExit(2) }
精彩评论