Home > Enterprise >  Exit only if $return -eq 'exit' always exits
Exit only if $return -eq 'exit' always exits

Time:10-28

I have a main script that calls several sub scripts that may run into an error. When they do, they exit nicely but so should the main script. Therefore, I implemented variations on the following statement in several locations of the sub scripts:

$testSomething = Test-Path $something
if (-not $testSomething) {
    write-host 'error message'
    return 'exit'
    exit
}

The main script calls the sub scripts thusly:

$return = .\subScript.ps1 parameter1 etc.

After which I figured this:

if ($return -eq 'exit') {
    Read-Host -Prompt 'Press Enter to exit'
    exit
}

However, the main script always exits regardless if the sub script encounters an error or not. I triple checked that it doesn't go into any of the if statements that return the value 'exit' and yet it exits. What am I overlooking?

Edit: Per request, below is the main script in its entirety (only the first two sub scripts can generate a show stopping error). This version is after a fruitless attempt to get the above to work by changing the if statements in the sub scripts to the following, which results in the script never exiting:

$testSomething = Test-Path $something
if (-not $testSomething) {
    $result = $null
    return $result
    exit
}

Main script:

param (
    [parameter(mandatory)] [string] $versie,
    [parameter()] [string] $versieSoort,
    [parameter()] [string] $dataSet,
    [parameter()] [string] $rollBack,
    [parameter()] [switch] $updateDataOnly,
    [parameter()] [string] $scriptMapLokaal
)

if (!$dataSet) {
    $dataSet = 'standaard'
}
if (!$scriptMapLokaal) {
    $scriptMapLokaal = 'C:\UpdateScript'
}

$stopWatch = [System.Diagnostics.Stopwatch]::StartNew()

$buildDrop = '\\somewhere'
$dataPadNetwerk = '\\somewhereElse'

Set-Location $PSScriptRoot

$return = .\Subscripts\1_checkVoorwaarden.ps1 -versie $versie -versieSoort $versieSoort -dataSet $dataSet -rollBack $rollBack -updateDataOnly $updateDataOnly -scriptMapLokaal $scriptMapLokaal -buildDrop $buildDrop -dataPadNetwerk $dataPadNetwerk
if (-not $return) {
    $stopWatch.Stop()
    Read-Host -Prompt "`nHet script is beëindigd. Toets Enter om af te sluiten"
    exit
}

$return = .\Subscripts\2_afleidenParameters.ps1 -versie $versie -versieSoort $versieSoort -dataSet $dataSet -rollBack $rollBack -updateDataOnly $updateDataOnly -scriptMapLokaal $scriptMapLokaal -buildDrop $buildDrop -dataPadNetwerk $dataPadNetwerk -versieNieuwstLokaal $versieNieuwstLokaal
if (-not $return) {
    $stopWatch.Stop()
    Read-Host -Prompt "`nHet script is beëindigd. Toets Enter om af te sluiten"
    exit
} else {
    if (!$versieSoort) {
        $versieSoort = $return[0]
    }
    $buildMapNetwerk = $return[1]
    $buildPadNetwerk = $return[2]
}

.\Subscripts\3_kopierenBuild.ps1 -versie $versie -versieSoort $versieSoort -updateDataOnly $updateDataOnly -scriptMapLokaal $scriptMapLokaal -buildMapNetwerk $buildMapNetwerk -buildPadNetwerk $buildPadNetwerk

if ($rollBack) {
    .\Subscripts\4_verwijderInstallaties.ps1 -versie $versie -versieSoort $versieSoort -rollBack $rollBack
}

if (-not $updateDataOnly -or !$updateDataOnly) {
    .\Subscripts\5_installerenBuild.ps1 -versie $versie -versieSoort $versieSoort -scriptMapLokaal $scriptMapLokaal -buildMapNetwerk $buildMapNetwerk
}

.\Subscripts\6_updateData.ps1 -versie $versie -versieSoort $versieSoort -dataSet $dataSet -scriptMapLokaal $scriptMapLokaal -dataPadNetwerk $dataPadNetwerk -buildMapNetwerk $buildMapNetwerk

if (-not $updateDataOnly -or !$updateDataOnly) {
    .\Subscripts\7_installerenNxtClient.ps1 -versieSoort $versieSoort -scriptMapLokaal $scriptMapLokaal
}

$stopWatch.Stop()
$aantalSeconden = $stopwatch.Elapsed.Seconds
Read-Host -Prompt "`nScript voltooid in $aantalSeconden seconden. Toets Enter om af te sluiten"

CodePudding user response:

Your subscript would never reach its exit statement. Your main script only check for -not $return. There are quiet some values that would evaluate as true in this case.

-not will try to negate the value. Negating $null, which is going to be the return value of your script unless your test fails, will be $true so your script will exit.

Rather than using the -not make it explicit and actually do what you suggested in your initial statement - check for the string exit.

$x = $null
if(-not $x){Write-Output "X is not false"}

CodePudding user response:

To my opinion exit closes the session.

If you just want to leave the sub-function you can just as well use return. Just plain "Return" return would return nothing but return 'Exit' would feed the $return variable in the main script with the string "Exit".

Return is the way to leave a function either empty or loaded as I call it. When loaded you can further the process the load from the main script.

If you use a try{}catch{} you can do something like this:

Try{
    "some code to test"
}
Catch {Return $error[0]}
Return "success"

Any failure but be catched by the catch the return makes you leave the function. Feeding the $Result variable in the main script with whatever is in $Error[0] after which the next statement in the main script is processed.

Maybe This link will help.

  • Related