0

On Saturday and Sunday the file may not be created which this script scans for its pattern match - where should I place a test if the file exists -before the While Loop or inside it? It runs great when the file exists - but on the Saturday run - it didn't exit and was still running Monday morning.

If(!( Test-Path -Path $Directory\$Source)) {exit or break?}

HEREs the current code ---


$job = Start-Job {
    # Note: $file should be the absolute path of your file
    Get-Content $File -Raw | Select-string -Pattern "Idle" -Quiet
}

while($true)
{
    # if the job has completed
    if($job.State -eq 'Completed')
    {
        $result = $job|Receive-Job

        # if result is True
        if($result)
        {
            $elapsedTime.Stop()
            $duration = $elapsedTime.Elapsed.ToString("hh\:mm\:ss")
            
            # .... send email logic here
            # for success result

            break #=> This is important, don't remove it
        }

        # we don't need a else here,
        # if we are here is because $result is false
        
        $elapsedTime.Stop()
        $duration = $elapsedTime.Elapsed.ToString("hh\:mm\:ss")

        # .... send email logic here
        # for unsuccessful result
        
        break #=> This is important, don't remove it
    }

    # if this is running for more than
    # 60 minutes break the loop
    if($elapsedTime.Elapsed.Minutes -ge 60)
    {
        $elapsedTime.Stop()
        $duration = $elapsedTime.Elapsed.ToString("hh\:mm\:ss")
        
        # .... send email logic here
        # for script running longer 
        # than 60 minutes

        break #=> This is important, don't remove it
    }
    
    Start-Sleep -Milliseconds 500
}

Get-Job|Remove-Job ```
Configueroa
  • 315
  • 4
  • 14
  • `break` exits out of script blocks and functions. Sure it will work in files if you are not nested in anything but if you want to *exit a file* use exit but if you instead want to *return something* from a file or are using a file like a function (which might I add, you can just use a function in here and import it then call the function) you could theoretically use `break` or `return` but that would be unorthodox. – Nico Nekoru Jun 21 '21 at 17:43
  • It is not entirely clear, what "the file" is: you have a `Get-Content` with `$File`, and nowhere else after it you have any paths. So if the `Test-Path` has anything to do with `$File$`, then it should be before `Get-Content`. – Dávid Laczkó Jun 21 '21 at 17:52
  • 1
    Good advice to use `exit`, @NicoNekoru, but the framing of `break` isn't quite correct; please see my answer for details. – mklement0 Jun 21 '21 at 17:54

1 Answers1

1
  • To exit a script as a whole (even from a function inside a script), use exit.

    • If you use exit outside a script:

      • An interactive session is terminated as a whole.
      • exit inside a job's script block (started with Start-Job or Start-ThreadJob) terminates that job (though its prior output, if any, can still be retrieved with Receive-Job).
    • To exit just a function, use return.

  • break and continue should only ever used to break out of loops (foreach / for, while, do) and switch statements.

    • Pitfall: If you use break or continue without an enclosing loop or switch statement, PowerShell looks up the call stack for such a statement and exits the first such statement it finds; if there is none, the current call stack is terminated. That is, at the very least the enclosing script terminates.
      That is, break can situationally, accidentally act like exit (without the ability to specify an exit code), but you should never rely on that.

See the bottom section of this answer for more information.

mklement0
  • 382,024
  • 64
  • 607
  • 775
  • can you `break` out of functions? – Nico Nekoru Jun 21 '21 at 17:57
  • @NicoNekoru, no: only `return` should be used to exit _functions_. `break` would again go looking up the call stack for an enclosing loop and terminate the script as a a whole if none is found. – mklement0 Jun 21 '21 at 18:02