John Anthony
asked on
powershell exit codes
Hi team need help on exit codes. I have a script that returns pass if all the conditions are passed . returns fail if one of the condition is fail.
if((alltest) -eq 'Pass')
{
Write-Host "Sucess"
Out-File -FilePath $SucessOutfile
$global:ExitCode = 0
[System.environment]::Exit (0)
}
else {
Write-Host "Failure"
Out-File -FilePath $FailureOutfile
$global:ExitCode = 1 #Set the exit code for the Packager
[System.environment]::Exit (1)
works fine when working with powershell ISE but when run with SCCM it will return always 0 even those the condition as return 1
if((alltest) -eq 'Pass')
{
Write-Host "Sucess"
Out-File -FilePath $SucessOutfile
$global:ExitCode = 0
[System.environment]::Exit
}
else {
Write-Host "Failure"
Out-File -FilePath $FailureOutfile
$global:ExitCode = 1 #Set the exit code for the Packager
[System.environment]::Exit
works fine when working with powershell ISE but when run with SCCM it will return always 0 even those the condition as return 1
[System.environment]::Exit (1) will definitely end the script with an errorlevel of 1.
But there are other things to consider:
* Is that script started directly or from some wrapper? If the latter, are you sure that the wrapper will pass the exitcode through?
* You're setting a global variable ExitCode "#Set the exit code for the Packager" - are you sure this "Packager" is evaluating that variable?
* Are all paths that can cause an error guaranteed to set an errorlevel <> 0? If the script encounters a terminating error, and you don't have a surrounding Try/Catch, it might just die and return with 0.
Run this, for example, from a cmd shell as "powershell.exe -File C:\Temp\ExitCode.ps1", then "echo %errorlevel%", and you'll find an errorlevel of 0.
But there are other things to consider:
* Is that script started directly or from some wrapper? If the latter, are you sure that the wrapper will pass the exitcode through?
* You're setting a global variable ExitCode "#Set the exit code for the Packager" - are you sure this "Packager" is evaluating that variable?
* Are all paths that can cause an error guaranteed to set an errorlevel <> 0? If the script encounters a terminating error, and you don't have a surrounding Try/Catch, it might just die and return with 0.
Run this, for example, from a cmd shell as "powershell.exe -File C:\Temp\ExitCode.ps1", then "echo %errorlevel%", and you'll find an errorlevel of 0.
Write-Host "foo"
Throw "Thrown out"
[System.environment]::Exit(666)
Write-Host "bar"
Did you specify the following command as posted ?
powershell.exe E:\Pre_Check\test6.ps1 exit /b %errorlevel%
Otherwise you could try:powershell.exe E:\Pre_Check\test6.ps1 && exit /b %errorlevel%
ASKER
we are running a batch file in SCCM. this batch file while call the PS script
Then it's likely that this batch file swallows the exit code.
So save this as C:\Temp\ExitCode.ps1
Both should return 666.
If the batch wrapper doesn't, then it's the wrapper's fault, not the PS script's.
So save this as C:\Temp\ExitCode.ps1
[System.environment]::Exit(666)
Then run it from a cmd prompt aspowershell.exe -File C:\Temp\ExitCode.ps1
echo %errorlevel%
Then run it using your batch wrapper.Both should return 666.
If the batch wrapper doesn't, then it's the wrapper's fault, not the PS script's.
ASKER
$global:ExitCode = 1 I used for testing. both [System.environment]::Exit(1) are giving same output
ASKER
powershell.exe -File C:\Temp\ExitCode.ps1
echo %errorlevel% no luck with this still getting true
value
echo %errorlevel% no luck with this still getting true
value
You're most certainly did not get "true", at least if you ran it from a cmd prompt as I suggested.
This is the expected behavior when you run the "[System.environment]::Exi t(666)" as described:
1. you run it exactly as described?
2. when let the wrapper start ExitCode.ps1 the same way it would start your original script in SCCM?
This is the expected behavior when you run the "[System.environment]::Exi
C:\>powershell.exe -File C:\Temp\ExitCode.ps1
C:\>echo %errorlevel%
666
So what are the results when 1. you run it exactly as described?
2. when let the wrapper start ExitCode.ps1 the same way it would start your original script in SCCM?
C:\Temp\wrapper.cmd
echo %errorlevel%
ASKER
I ran the script in same way
powershell.exe -File C:\Temp\ExitCode.ps1
C:\>echo %errorlevel%
I got errorlevel value as 0
powershell.exe -File C:\Temp\ExitCode.ps1
C:\>echo %errorlevel%
I got errorlevel value as 0
ASKER
if((alltest) -eq 'Pass')
{
Write-Host "Sucess"
Out-File -FilePath $SucessOutfile
#$global:ExitCode = 0
[System.environment]::Exit(0)
}
else {
Write-Host "Failure"
Out-File -FilePath $FailureOutfile
# $global:ExitCode = 1 #Set the exit code for the Packager
[System.environment]::Exit(666)
}
{
Write-Host "Sucess"
Out-File -FilePath $SucessOutfile
#$global:ExitCode = 0
[System.environment]::Exit(0)
}
else {
Write-Host "Failure"
Out-File -FilePath $FailureOutfile
# $global:ExitCode = 1 #Set the exit code for the Packager
[System.environment]::Exit(666)
}
That is not what I asked you to do.
Save only this one line as C:\Temp\ExitCode.ps1
Save only this one line as C:\Temp\ExitCode.ps1
[System.environment]::Exit(666)
Then run it once as described above, once integrated into the wrapper.
ASKER
when I am running double click opening with powershell also I am getting 0
only working fine with PS ISE
only working fine with PS ISE
Calling it directly is as it should be.
When you run it from Explorer, Explorer will start powershell.exe with the file, and nobody will ever get to see the errorlevel, because Explorer doesn't care at all.
And again: what is the errorlevel when you let your wrapper batch script start that exact same C:\Temp\ExitCode.ps1?
Do not run it from Explorer. Run the wrapper from an open cmd prompt, and then the "echo %errorlevel%"
When you run it from Explorer, Explorer will start powershell.exe with the file, and nobody will ever get to see the errorlevel, because Explorer doesn't care at all.
And again: what is the errorlevel when you let your wrapper batch script start that exact same C:\Temp\ExitCode.ps1?
Do not run it from Explorer. Run the wrapper from an open cmd prompt, and then the "echo %errorlevel%"
ASKER
its showing 0
Well, then the culprit is obviously the wrapper script.
You're probably calling the script, then doing something else, then quitting.
You need to save the errorlevel immediately after running powershell.exe, then leave the script with "exit /b <PSErrorLevel>"
Like this:
You're probably calling the script, then doing something else, then quitting.
You need to save the errorlevel immediately after running powershell.exe, then leave the script with "exit /b <PSErrorLevel>"
Like this:
... whatever
powershell.exe ...
set PSErrorLevel=%ErrorLevel%
... whatever
exit /b %PSErrorLevel%
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
values are returning properly
ASKER
Hi oBdA it worked actually script was fine... but return variable was not declared as global.
ASKER
Thanks for the support
Maybe it's due to SCCM. Can you maybe tell how it's launched from SCCM. Are you using a cmd file which starts powershell.exe or do you run it directly.