Reputation: 15423
$res = Invoke-Sqlcmd -Query "select * from customer" -ServerInstance "(localdb)\MSSQLLocalDB" -Database "Database1" -OutputAs DataTables
$res | Where-Object FirstName -eq "John"
$res.Where({$_.FirstName -eq "John"})
This is the output:
Id FirstName City
-- --------- ----
1 John Augusta
1 John Augusta
I was expecting this:
Id FirstName City
-- --------- ----
1 John Augusta
Id FirstName City
-- --------- ----
1 John Augusta
Upvotes: 2
Views: 105
Reputation: 437062
Building on the helpful comments:
The behavior is by design:
Objects output by a given script or a single interactively submitted command line are all sent to the success output stream of a single pipeline.
When output from a pipeline is neither captured nor redirected, PowerShell applies for-display output formatting to all output objects in the success output stream of a given pipeline, and if the first output object implicitly selects tabular formatting, all subsequent objects of the same type are formatted as part of the same table that is printed to the host (display, terminal).
[pscustomobject]
instances, but with different property sets - see this answer for more information.If you want to format a given command's output individually, you have three basic options, all of which are suboptimal in case you also want to option to later programmatically process the output, not just format it for display:
Send the output directly to the host, using Out-Host
:
$res | Where-Object FirstName -eq "John" | Out-Host
Use a Format-*
cmdlet such as Format-Table
explicitly:
$res | Where-Object FirstName -eq "John" | Format-Table
Use Out-String
(possibly preceded by a call to a Format-*
cmdlet to select the kind of formatting and/or control the specifics of the formatting):
$res | Where-Object FirstName -eq "John" | Out-String
Out-Host
[1] and since strings always render as-is, you'll see the same host output; in programmatic processing, these strings are relatively more meaningful than the formatting-instruction objects output by Format-*
cmdlets, but still amount to a loss of information compared to the original output objects.[1] Unfortunately, Out-String
always appends a trailing newline to this representation; this problematic behavior is the subject of GitHub issue #14444. As zett42 points out, using Out-String -Stream
avoids this problem, albeit at the expense of sending the lines of the multi-line string representation individually to the output stream; To avoid that, you can use (... | Out-String -Stream) -join "`n"
Upvotes: 5