checking the status of command executed successfully - powershell

Sorry I am a newbie in PowerShell. I am running a script which executes some commands to copy files from a system.. Is there a way to capture the status of the command whether it completed successfully before moving to the next command?
For example:
$scp_cmd = "scp.exe -a root#192.168.1.1:/files/repo1 /repo1"
$rsync_cmd = "rsync.exe -tvP root#192.168.1.2:/files/repo2 /repo2"
Invoke-Expression $scp_cmd
# How do we check whether the command completed successfully?
Invoke-Expression $rsync_cmd
# How do we check whether the command completed successfully?

Use the $LASTEXITCODE automatic variable. It works both with Invoke-Expression and the & call operator:
$rsync_cmd = "rsync.exe -tvP root#192.168.1.2:/files/repo2 /repo2"
Invoke-Expression $rsync_cmd
if($LASTEXITCODE)
{
# exit code from rsync was not 0
}

Related

gracefully exit from program spawned by powershell script

Lets assume I have the following script:
$originalPath=pwd
D:\code\ps1\misc\title.ps1 "dynamo db"
$CURPATH = "$PSScriptRoot\path.txt"
$DB_DIR= cat $CURPATH
cd $DB_DIR
java -D"java.library.path=./DynamoDBLocal_lib" -jar DynamoDBLocal.jar
cd $originalPath
This script starts the java program correctly, however, when I hit CTRL+C, the last cd command is not executed.
Is this by design for powershell? Or can I change this?
Written as of PowerShell Core 7.2.5.
When you use Ctrl-C to abort an external program, the current PowerShell script (runspace) is terminated too.
While you cannot prevent your script from getting terminated, you can perform clean-up actions, namely in the finally block of a try / catch / finally statement:
$originalPath = $PWD
# ...
try {
cd $DB_DIR
java -D"java.library.path=./DynamoDBLocal_lib" -jar DynamoDBLocal.jar
} finally {
# This block is *always* executed, but limitations apply
# if Ctrl-C was pressed:
# * Execution invariably ends with this block.
# * You cannot output to the success output stream or error stream,
# neither explicitly nor implicitly: doing so quietly and instantly
# aborts processing.
# * However, the *other* output streams *can* be targeted, namely with
# the following cmdlets (but note that except for Write-Host and Write-Warning,
# producing visible output is opt-in):
# Write-Host, Write-Warning, Write-Verbose, Write-Debug, Write-Information
cd $originalPath
}

Powershell exitcode from MDM

I'm writing a powershell script that:
Downloads a file
Checks it's hashsum
If hashsum is correct it installs it
If hashsum is incorrect it does not install it
I have a problem, where I'm using an MDM to deploy it automatically on many machines at the same time. Feedback from MDM shows that installation failed - but installed file works as intended for sure. Therefore most likely MDM receives bad return value. MDM exits code are like this
Success exit code equal 0
Failed exit code not equal 0
So: How to make sure powershell script return Success after 3. If hashsum is correct it installs it
Will $LASTEXITCODE = 0 make it work?
Just use exit and the exit code you want. Like:
Function CustomExit{
Write-Output "This function returns exit code 1613"
Exit 1613 # Custom Exit Code
}
CustomExit
to test just run the file and give out the exitcode
PS C:\script> .\CustomExitCode.ps1
This function returns exit code 1613
PS C:\script> $LASTEXITCODE
1613
PS C:\script>

AzCopy: How to know if the copy was success or not

I have a script in Ubuntu that copy only one file each hour to the Storage Account. I am using azcopy filename.tar https://<storage>.blob.core.windows.net/<container>.
This script is working but I'd like to check if the copy was success or not, for example:
validcopy = azcopy copy filename.tar https://<storage>.blob.core.windows.net/<container>
if(validcopy){
echo "Success"
} else {
echo "Failure"
}
Also, I tried using Power Shell in linux (pwsh), but unsuccess.
Please, can someone help me?
I got a alternative solution for this issue.
I used exit code in bash shell. Every Linux or Unix command executed by the shell script or user has an exit status. Exit status is an integer number. 0 exit status means the command was successful without any errors. A non-zero (1-255 values) exit status means command was a failure.
A particular shell variable called $? to get the exit status of the previously executed command
It was like this:
azcopy copy filename.tar https://<storage>.blob.core.windows.net/<container>
if [[ $? -gt 0 ]]
then
echo "Failure"
else
echo "Success"
fi

Run command in powershell and ignore exit code in one line

I try to execute a command in powershell and ignore any non zeroexit code. Unfortunately I completely fail doing this :-(
Under Linux this is done with this trivial line:
command arg1 arg2 || echo "ignore failure"
The or clause is executed only in case of a failure and then the exit code of echo resets $?
I thought something like this would do the trick:
Invoke-Expression "command arg1 arg2" -ErrorAction Ignore
But $LASTEXITCODE is still set to a non zero value
PowerShell v7+'s pipeline-chain operators, && and ||, implicitly act on $LASTEXITCODE, but never reset it.
If you do want to reset it - which is generally not necessary - you can do the following:
command arg1 arg2 || & { "ignore failure"; $global:LASTEXITCODE = 0 }
Note that PowerShell scripts - unlike scripts for POSIX-compatible shells such as bash - do not implicitly exit with the exit code of the most recently executed command; instead, you must use exit $n explicitly, where $n is the desired exit code.
In the context of calling the PowerShell CLI from the outside, the above applies to using the -File parameter to call a script; for use with the -Command (-c) parameter, see the next section.
As for what you tried:
|| and && don't work in Windows PowerShell (versions up to v5.1) at all.
Invoke-Expression doesn't help here and should generally be avoided and used only as a last resort, due to its inherent security risks. In short: Avoid it, if possible, given that superior alternatives are usually available. If there truly is no alternative, only ever use it on input you either provided yourself or fully trust - see this answer.
If you're using the Windows PowerShell CLI with -Command (-c), and you need to make sure that the PowerShell process exits with exit code 0, do something like the following (... represents your command):
powershell.exe -noprofile -c "...; exit 0"
If you want to comment on the failure:
powershell.exe -noprofile -c "...; if ($LASTEXITCODE) { 'ignore failure' }; exit 0"
Note: In this case, ; exit 0 isn't strictly necessary, because the if statement alone, due to it succeeding, irrespective of the value of $LASTEXITCODE, is enough to make the exit code 0.
Also, note that PowerShell CLI sends all of PowerShell's output streams - including the error stream - to stdout by default, though you can selective redirect the error stream on demand with 2>.
This also applies to the PowerShell [Core] v7+ CLI, whose executable name is pwsh, and whose parameters are a superset of the Windows PowerShell CLI.
For more information on PowerShell with respect to process exit codes, see this answer.

Dot-sourcing PowerShell script file and return code

Here's some PowerShell code:
test.ps1:
. C:\path\to\test2.ps1
exit 5
test2.ps1:
exit 7
Run test.ps1 from a standard command prompt however you like to run PowerShell scripts, then call:
echo %errorlevel%
The expected result is a return code of 7. This is the first exit command in the PowerShell script. The actual result, however, is a return code of 5. Obviously the included script was terminated but its return code was ignored and the calling script happily continued.
How can I really terminate a script and return a result code no matter how it was called?
Or alternatively, how should I call test2.ps1 so that its return code is passed on to the outside world?
Background: My build script is made with PowerShell and it includes module files for different tasks. One task currently fails and the build server didn't detect the error because my start build script still returned 0.
You should query $lastExitCode that would have nonzero value if the last script/program exited with failure. So, your sample's test1.ps1 should be like this:
. C:\path\to\test2.ps1
if ($lastexitcode -ne 0) { exit $lastexitcode}
exit 5