When piping the output of a command to a ForEach-Object
loop in PowerShell, using a continue
statement causes it to error out.
Works as expected:
ipconfig | ForEach-Object {
$_
}
Errors:
ipconfig | ForEach-Object {
$_
continue
}
The error is
Program 'ipconfig.exe' failed to run: System error.At C:\Users\test\ps.ps1:1 char:1
+ nslookup google.com | ForEach-Object {
+ ~~~~~~~~~~~~~~~~~~~.
At C:\Users\test\ps.ps1:1 char:1
+ nslookup google.com | ForEach-Object {
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ResourceUnavailable: (:) [], ApplicationFailedException
+ FullyQualifiedErrorId : NativeCommandFailed
This seems to happen with any external command, such as nslookup
and net
I thought maybe this had to do with some type conversion, but the object inside the loop is always a string. Saving the command output to a variable, and then doing a $var | ForEach-Object
works.
continue
statements in PowerShell can only be used within loop constructs. While ForEach-Object
seems like a loop, it's not.
In PowerShell, you can technically use continue
outside of a loop, but it causes PowerShell to not find a loop, and just terminate the current runspace.1
This means PowerShell can actually terminate the caller1, and looking at the callstack, that caller is the "parent" line and so it is terminated.
Callstack right before the continue
executes:
ScriptLineNumber : 4
Position : continue
FunctionName : <ScriptBlock>
ScriptLineNumber : 1
Position : net help | ForEach-Object {
$_.GetType()
continue
}
FunctionName : <ScriptBlock>
Instead, use a return
statement.
Reference