PowerShell vs CMD Pipe Behavior: Why “find.exe” Fails with “netstat” Output


2 views

When running network diagnostics, many Windows administrators use the classic combination:

netstat -an | find "443"

This works perfectly in Command Prompt (cmd.exe), but fails in PowerShell with the error:

FIND: Parameter format not correct

The root cause lies in how PowerShell handles piping compared to cmd.exe. PowerShell's pipeline works with .NET objects rather than raw text streams. When you pipe to find.exe (a legacy command), the data format isn't compatible by default.

1. Use findstr (native Windows command):

netstat -an | findstr "443"

2. PowerShell's Select-String:

netstat -an | Select-String "443"

3. Force text output with Out-String:

netstat -an | Out-String -Stream | find "443"
  • findstr understands both cmd and PowerShell piping behavior
  • Select-String is PowerShell's native string search cmdlet
  • Out-String converts the output to raw text format that find.exe expects

To see the actual data being piped, use:

netstat -an | Get-Member
netstat -an | Format-List *

This reveals PowerShell is handling the output as System.String objects rather than a raw text stream.

For large network outputs:

# findstr is fastest for simple searches
netstat -an -p tcp | findstr "LISTENING"

# Select-String offers more flexibility
netstat -an | Select-String -Pattern "443|80" -Context 2

# For complex parsing, convert to objects
$connections = netstat -an | Select-String "\d+\.\d+\.\d+\.\d+" | ForEach-Object {
    $_.Line -match "(?\S+)\s+(?\S+)\s+(?\S+)\s+(?\S+)" | Out-Null
    [PSCustomObject]$matches
}

When executing netstat -an | find "443" in PowerShell, you'll encounter the error:

FIND: Parameter format not correct

This works perfectly in Command Prompt (cmd.exe) but fails in PowerShell. Meanwhile, these PowerShell alternatives work:

netstat -an | findstr "443"
netstat -an | Select-String "443"

The issue stems from how PowerShell handles text encoding and stream redirection differently from cmd.exe. find.exe is a legacy command-line tool that expects:

  • Raw text input in OEM encoding (like cmd provides)
  • Simple stream handling without PowerShell's rich object pipeline

PowerShell transforms the output stream before piping to external commands:

# What PowerShell actually does internally:
$output = netstat -an | Out-String -Stream
$output | & find.exe "443"  # Fails due to encoding mismatch

Here are three reliable approaches:

1. Use findstr (Recommended)

netstat -an | findstr "443"

findstr.exe handles PowerShell's output correctly and has similar syntax to find.

2. PowerShell Native Alternative

netstat -an | Select-String "443"

Select-String is PowerShell's built-in equivalent with additional features:

# Case-insensitive search with context
netstat -an | Select-String "443" -Context 2,2

3. Force Correct Encoding (For find.exe Purists)

cmd /c 'netstat -an | find "443"'

Or more explicitly:

netstat -an | Out-String -Stream | % { [System.Text.Encoding]::Convert(
    [System.Text.Encoding]::UTF8,
    [System.Text.Encoding]::GetEncoding(850),
    [System.Text.Encoding]::UTF8.GetBytes($_)) 
} | find "443"

When processing large outputs:

  • findstr is ~2x faster than Select-String for simple matches
  • Select-String has better regex support for complex patterns
  • The cmd /c method adds minimal overhead

For more powerful filtering:

# Get only ESTABLISHED 443 connections
netstat -an | Select-String "443" | Where { $_ -match "ESTABLISHED" }

# Using regex groups with findstr
netstat -an | findstr /R "443.*ESTABLISHED"

For PowerShell Core (7+) on Linux/macOS:

netstat -an | grep "443"