I have the following code:
$ExitCode = Get-Random -InputObject 0, 1
Exit $ExitCode
It seems to always return 0 as an exit code.
I don't know if I have coded the exit wrong or if Get-Random
does not allow setting it to a variable.
All the samples I see on the internet of Get-Random
have it printing to the console.
How do I get the code to exit with a random 0 or 1?
[EDIT]
I am beginning to think the problem is with the Exit
.
I coded this:
$ExitCode = Get-Random -InputObject 0, 1
#Exit $ExitCode
Exit 1
and I still get exit code 0. I am running this script from VisualCron. So it could also be VisualCron mucking with the exit code. I have run it at least 12 times I don't think Get-Random could be returning 0 every time.
It seems to always return 0 as an exit code.
No: With just 2 possible random values, it's not uncommon to receive the same value multiple times in a row.
In other words: your code intrinsically works fine, it may just be surprising that the same value can be reported multiple times in a row.
However, independently, the actual exit code may get lost, depending on how your script is invoked via the PowerShell CLI, which is what VisualCron also allows you to use - see bottom section.
You can verify that you'll eventually get both values with the following snippet, which prints the - randomly varying - number of iterations until both values have been returned:
$count = 0
$have0 = $have1 = $false
do {
++$count
$val = Get-Random -InputObject 0, 1
if ($val -eq 0) { $have0 = $true }
else { $have1 = $true }
if ($have0 -and $have1) { break }
} while ($true)
"Both 0 and 1 returned after $count attempts."
You'll typically see values in the single-digit range, i.e., fewer than 10 invocations.
The problem is that the PowerShell CLI (calling powershell.exe
with arguments) doesn't always pass a script's exit
code value through, depending on how it was invoked:
If you use -File
to invoke the script (which you should, if all you do is invoke a single script), the script's exit code - assuming it is explicitly set with exit
- is properly passed through (reported as powershell.exe
's exit code.
By contrast, if you use -Command
(-c
), it is the success status - as PowerShell internally reflected in the automatic $?
variable - of the last command or expression that is reported, which has the following implications:
If invocation of your script is the last command passed to -Command
, its exit code gets mapped onto 0
or 1
; that is, 0
is passed through, but any nonzero value is reported as 1
.
If invocation of your script is not the last command, it is that last command's success status that determines the overall exit code (again, 0
or 1
); note that something as subtle as enclosing your script invocation in (...)
makes it no longer the last command in versions up to 6.x.
See this answer for additional information.
Therefore, to ensure that your script's exit code set with exit <n>
is passed through:
Use -File
, if possible.
If you must use -Command
, because additional commands must be executed:
append ; exit $LASTEXITCODE
to your -Command
argument (which you would also do if you called an external program whose exit code you wanted to pass through).
alternatively, as in your own answer, you can use throw
inside your script to force reporting of exit code 1
, but note that throw
aborts processing instantly, so that the remaining commands passed to -Command
are then not executed.