Kismet Agbasi
Kismet Agbasi

Reputation: 567

How Do I Exit While Loop From Within a Switch Statement

In PowerShell, how do I exit this while loop that is nested inside a switch statement, without executing the code immediately following the while block? I can't seem to figure it out. Everything I've tried so far results in that block of code being executed.

Here's what I'm trying to accomplish:

  1. Check for the presence of a file and notify user if file is detected.
  2. Check again every 10 seconds and notify user
  3. If the file is not detected, then exit the loop and switch, and continue with Step #2
  4. If the file is still detected after 30 seconds, timeout and exit the script entirely.

Here's the code:

try {
    #Step 1
    $Prompt = <Some Notification Dialog with two buttons>
    switch ($Prompt){
        'YES' {
            # Display the Windows Control Panel

            #Wait for user to manually uninstall an application - which removes a file from the path we will check later.
            $Timeout = New-Timespan -Seconds 30
            $Stopwatch = [Dispatch.Stopwatch]::StartNew()

            while ($Stopwatch.elapsed -lt $Timeout) {
                if (Test-Path -Path "C:\SomeFile.exe" -PathType Leaf) {
                    Write-Host "The file is still there, remove it!"
                    return
                }
                Start-Sleep 10
            }

            #After timeout is reached, notify user and exit the script
            Write-Host "Timeout reached, exiting script"
            Exit-Script -ExitCode $mainExitCode #Variable is declared earlier in the script
        }
        'NO' {
            # Do something and exit script
        }
    }

    # Step 2
    # Code that does something here

    # Step 3
    # Code that does something here
} catch {
    # Error Handling Code Here
}

Upvotes: 3

Views: 2315

Answers (2)

js2010
js2010

Reputation: 27491

Is that what you see without the try/catch? I get an exception: Unable to find type [Dispatch.Stopwatch]. Otherwise the return works ok for me.

I think what you want is break with a label going outside the switch? Then steps 2 & 3 will run. I altered the code to make a manageable example. This is more ideal when asking a question. I don't know what exit-script is.

echo hi > file

#try {
    #Step 1
    $Prompt = '<Some Notification Dialog with two buttons>'
    $Prompt = 'yes'
:atswitch    switch ($Prompt){
        'YES' {
            'Display the Windows Control Panel'

            #Wait for user to manually uninstall an application - which removes a file from the path we will check later.
            $Timeout = New-Timespan -Seconds 30
            #$Stopwatch = [Dispatch.Stopwatch]::StartNew()

            while (1) {
                if (Test-Path -Path "file" -PathType Leaf) {
                    Write-Host "The file is still there, remove it!"
                    break atswitch
                }
                Start-Sleep 10
            }

            #After timeout is reached, notify user and exit the script
            Write-Host "Timeout reached, exiting script"
            'Exit-Script -ExitCode $mainExitCode #Variable is declared earlier in the script'
        }
        'NO' {
            'Do something and exit script'
        }
    }

    # Step 2
    'Code that does something here'

    # Step 3
    'Code that does something here2'
#} catch {
#    'Error Handling Code Here'
#}

Upvotes: 1

Olaf Reitz
Olaf Reitz

Reputation: 694

You can use break with a label, to exit a specific loop (a switch statements counts as a loop), see about_break.

$a = 0
$test = 1
:test switch ($test) {
    1 {
        Write-Output 'Start'
        while ($a -lt 100)
        {
            Write-Output $a
            $a++
            if ($a -eq 5) {
                break test
            }
        }
        Write-Output 'End'
    }
}
Write-Output "EoS"

Upvotes: 6

Related Questions