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 ).