diff --git a/public/Stop-DbaExternalProcess.ps1 b/public/Stop-DbaExternalProcess.ps1 index a14dd22d3b5..5f6acc60bd4 100644 --- a/public/Stop-DbaExternalProcess.ps1 +++ b/public/Stop-DbaExternalProcess.ps1 @@ -95,7 +95,9 @@ function Stop-DbaExternalProcess { } } } catch { - Stop-Function -Message "Error killing $ProcessId on $ComputerName" -ErrorRecord $_ -Continue + # No -Continue here: this block has no enclosing loop, so the continue would escape the command + # and eat an iteration of whatever loop the caller runs in (#10638). + Stop-Function -Message "Error killing $ProcessId on $ComputerName" -ErrorRecord $_ } } } \ No newline at end of file diff --git a/tests/Stop-DbaExternalProcess.Tests.ps1 b/tests/Stop-DbaExternalProcess.Tests.ps1 index d9240b8d26c..a992abf31a3 100644 --- a/tests/Stop-DbaExternalProcess.Tests.ps1 +++ b/tests/Stop-DbaExternalProcess.Tests.ps1 @@ -92,4 +92,19 @@ Describe $CommandName -Tag IntegrationTests { $results.Status | Should -Be "Stopped" } } -} \ No newline at end of file + + Context "When the process does not exist" { + It "Warns without eating an iteration of the caller's loop" { + # The catch used to run Stop-Function -Continue at the end of the process block, where no loop + # encloses it - the continue escaped the command and consumed an iteration of this very loop, so + # the counter stayed at zero (#10638). Stop-Process on a process id that does not exist throws. + $loopCount = 0 + foreach ($i in 1..3) { + $null = Stop-DbaExternalProcess -ComputerName localhost -ProcessId 2147483647 -WarningAction SilentlyContinue -Confirm:$false + $loopCount++ + } + $loopCount | Should -Be 3 + ($WarnVar -join " ") | Should -BeLike "*Error killing 2147483647*" + } + } +}