'How to get the first row from a PowerShell datatable
In PowerShell, if $dt is a datatable, I am used to using foreach() to do row-by-row operations. For example...
foreach ($tmpRow in $dt) {
Write-Host $tmpRow.blabla
}
I just want to get the first row (of n columns). I could introduce a counter $i and just break the foreach loop on the first iteration, but that seems clunky. Is there a more direct way of achieving this?
Solution 1:[1]
For a collection (array) that is already in memory, use indexing, namely
[0]:Note: Normally,
$dt[0]should suffice, but in this case the index must be applied to the.Rowsproperty, as Theo advises:$dt.Rows[0].blabla
Given that PowerShell automatically enumerates a
System.Data.DataTableby enumerating theSystem.Data.DataRowinstances stored in its.Rowsproperty - both in the pipeline and in aforeachloop, as in your code - the need to specify.Rowsexplicitly for indexing is surprising.- With
$dtcontaining aSystem.Data.DataTableinstance,$dt[0]is actually the same as just$dtitself, because PowerShell in this context considers$dta single object, and generally supports indexing even into such single objects, in the interest of unified treatment of scalars and arrays - see this answer for background information.
- With
For command output, use
Select-Object -First 1. Using the example ofInvoke-SqlCmd(Invoke-SqlCommand ... | Select-Object -First 1).blablaNote: Since
Invoke-SqlCommandby default outputs individualSystem.Data.DataRowinstances (one by one), you can directly access property.blablaon the result.The advantage of using
Select-Object -First 1is that short-circuits the pipeline and returns once the first output object has been received, obviating the need to retrieve further objects.
Solution 2:[2]
PowerShell automatically enumerates all rows when you pipe a DataTable, so you could pipe it to Select-Object -First 1:
# set up sample table
$dt = [System.Data.DataTable]::new()
[void]$dt.Columns.Add('ID', [int])
[void]$dt.Columns.Add('Name', [string])
# initialize with 2 rows
[void]$dt.Rows.Add(1, "Clive")
[void]$dt.Rows.Add(2, "Mathias")
# enumerate only 1 row
foreach ($tmpRow in $dt |Select-Object -First 1) {
Write-Host "Row with ID '$($tmpRow.ID)' has name '$($tmpRow.Name)'"
}
Expected screen buffer output:
Row with ID '1' has name 'Clive'
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | Mathias R. Jessen |
