Pramod
Pramod

Reputation: 371

Exception handling in powershell when it's invoked from batch script

Unfortunately, my host application can't directly execute PowerShell scripts, so I have written a batch script which calls PowerShell script with content

@echo off
echo calling upgrade product with argument %2
if [%1] == [] (
    powershell -ExecutionPolicy UnRestricted -command "%~dp0Product1.ps1 "ProductConfig.xml" -verbose; exit $LASTEXITCODE"
) else (
cd %1
powershell -ExecutionPolicy UnRestricted -command "%1\UpgradeProduct.ps1 %2 -verbose; exit $LASTEXITCODE"
)

And in my powershell script i have code like

$ErrorActionPreference="Stop"
try{
    Copy-Item -Path $source -Destination $dest
}catch{
    Write-Warning "Some Error"
}

This executes fine when i execute the script from the PowerShell window(if $source is not found it will throw a terminating error and prints Some Error). But when executed from batch script if $source is not found Copy-Item throws a non terminating error and continues(Dosen't print Some Error).
How can i make the Copy-Item to throw a terminating error if $Source is not found?

Upvotes: 1

Views: 2615

Answers (1)

Manea
Manea

Reputation: 192

You have nothing that stop in your catch block. I presume Your Write-Warning is triggered, but code after your block is runned.

You must return something in your catch block, like:

$ErrorActionPreference="Stop"
try{
    Copy-Item -Path $source -Destination $dest
}catch{
    Write-Warning "Some Error"

    #$LASTEXITCODE is a special variable in powershell
    $LASTEXITCODE = 1
    exit $LASTEXITCODE
}

Note $LASTEXITCODE variable, it is a special variable, the equivalent to %errorlevel%, that is used by commands like "cmd calls" by PowerShell.

You can test it by using this command in PowerShell:

cmd.exe /c exit 5
$LASTEXITCODE

I suggest you to first do a check if path exists:

try{
    if(Test-Path $source){
        Copy-Item -Path $source -Destination $dest -ErrorAction Stop
    }else{
        Write-Warning "$source not found."
            $LASTEXITCODE = 1
                exit $LASTEXITCODE
    }
}catch{
    Write-Error "Exception during copy: $($_)"
        $LASTEXITCODE = 1
        exit $LASTEXITCODE
}

Point of interest: ErrorAction is used at Function level. Set it at script level will include this settings for many commands. Exception will be thrown only if copy fail for something else: bad ACL, overwrite etc.

Upvotes: 1

Related Questions