Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why won't the "Exit" function work in my PowerShell code?

Tags:

powershell

When I try the "Exit" function. It does not close the console. It doesn't do anything. How can I change it to make it exit the console?

Write-Host "-------------- MENU ---------------"
Write-Host "Utility Menu"
Write-Host "1 = Help Ipconfig"
Write-Host "2 = Ipconfig"
Write-Host "3 = Notepad"
Write-Host "4 = Calculator"
Write-Host "5 = Exit"
Write-Host "-----------------------------------"

$userinput = Read-Host "Please select a menu item: "

switch ( $userinput )
{
  1 {Help Ipconfig}
  2 {ipconfig}
  3 {start notepad}
  4 {start calc.exe}
  5 {Exit}
}
like image 244
Sydney Avatar asked Sep 15 '25 22:09

Sydney


1 Answers

There is helpful information in the existing answers, but I feel that conceptual framing is called for:

exit [...] It does not close the console.

It is unusual for a script to want to terminate the entire interactive PowerShell session (which is what would lead to the console window closing), and exit would only do so outside a script - see the bottom section for details.

If exiting the session as a whole from a script or function[1] is really your intent, use [Environment]::Exit(0), as suggested by Colyn1337. (0 is the exit code to report on process termination, which by convention signals success; when closing an interactive session, this exit code is likely irrelevant.)


Background information

Language keywords for exiting various scopes from PowerShell:

  • break is used to exit just a switch statement or a loop statement (foreach / for, while, do); that is, execution continues in the same scope after such a statement - see the conceptual about_Break help topic.

    • Pitfall: If you use break or continue without an enclosing loop or switch statement, PowerShell looks up the call stack for such a statement and exits the first such statement it finds; if there is none, the current call stack is terminated; that is, at the very least the enclosing script terminates as a whole.
      • Note that a ForEach-Object call (whose built-in aliases are % and, somewhat confusingly, foreach), invariably in a pipeline, is not a loop; to "break" out of a script block passed to ForEach-Object, i.e. to move on to the next pipeline input object, use return.
  • return is used to exit an enclosing script file (if executed directly in the script file's top-level scope) or function or script block ({ ... }), optionally by first outputting data via an expression or command passed as an argument (e.g. return 'foo'); see the conceptual about_Return help topic.

    • return has no effect on the exit code reported by a script and therefore potentially by a PowerShell process as a whole; only exit can be used to set the exit code - see below.
  • exit is used to exit an interactive session or the enclosing script file and to optionally set an exit code:

    • Outside of a script file, exit exits an interactive PowerShell session as a whole (closes the console window).

    • Inside of a script file, exit always exits that script (only) - even when called from a function inside that script.

      • Note the contrast with return, which from a function just exits that function, whether called from inside a script or not.
    • exit $exitCode - where $exitCode stands for any integer[2] - can be used to set a script / session's exit code; using just exit is the same as exit 0:

      • Since PowerShell's error handling isn't based on exit codes (unlike that of shells such as cmd.exe and bash), setting an exit code is primarily of interest for communicating success vs. failure to outside callers.

      • If you execute a script from the outside via PowerShell's CLI (e.g., pwsh -File script.ps1), the exit code set via exit $exitCode will also become the process exit code, which the outside caller - e.g., a CI tool - can then inspect.

        • Session-internally, an exit code set by a script via exit $exitCode is reflected in the automatic $LASTEXITCODE variable, though note that this variable is also set by any call to an external program, to that program's process exit code.
      • See this post for more information about the relevance and use of exit codes in PowerShell.


[1] As postanote's answer shows, exit from inside a function that has been dot-sourced (loaded directly into) the global scope, exits the whole session too. However, it is better to explicitly signal the unusual intent to exit the entire session via [Environment]::Exit(0).

[2] Technically, you can pass any expression or command to exit (as with return, though the expression/command's output becomes data there, as-is), but anything that cannot at least be converted to an integer - e.g., exit 'not a number' - is quietly ignored and is the same as exit 0. Also note that the range of valid integers varies by platform: Windows supports [int] values, i.e. signed 32-bit values that include negative numbers. By contrast, Unix-like platforms only support unsigned [byte] values, i.e. numbers from 0 to 255 (negative numbers are converted to positive ones, and only the lowest byte is considered for larger values ).

like image 105
mklement0 Avatar answered Sep 17 '25 18:09

mklement0