Skip to content
PowerShell FAQs
PowerShell FAQs
  • Home
  • PowerShell Commands
  • Start Here
    • Variables
    • Data Types
    • Array
    • Files
    • String
    • Datetime
  • SharePoint
  • Download
  • Blogs

How to Read a File Line by Line in PowerShell

Last Modified Date: September 28, 2026 by Bijay Kumar

To read a file line by line in PowerShell, loop over Get-Content. It returns one string per line, so a foreach loop handles each line in turn:

foreach ($line in Get-Content -Path C:\psfaqs\servers.txt) {
    "Checking $line"
}

Output:

Checking WEB01
Checking WEB02
Checking SQL01
Checking FILE01

Below I cover line numbers, reading into an array, the first and last lines, skipping a header, and one encoding problem in Windows PowerShell 5.1. I ran every example in PowerShell 7.6 and 5.1.

This Tutorial Covers:

Toggle
  • Show line numbers
  • Read a file into an array
    • The one-line file trap
  • Read the first or last line
  • Skip the first line
  • Why do special characters look wrong in Windows PowerShell 5.1?
  • Reading very large files
  • Frequently Asked Questions
    • How do I read a file line by line in PowerShell?
    • How do I read only the first line of a file?
    • How do I skip the first line of a file in PowerShell?
    • Why does $lines[0] return only one letter?
    • How do I get the line number while reading a file?

Show line numbers

Every line that Get-Content returns carries its line number in a ReadCount property, so you don’t need your own counter:

Get-Content -Path C:\psfaqs\servers.txt | ForEach-Object {
    "Line $($_.ReadCount): $_"
}

Output:

Line 1: WEB01
Line 2: WEB02
Line 3: SQL01
Line 4: FILE01
PowerShell read a file line by line with line numbers from ReadCount
Each line knows its own line number (PowerShell 7)

Read a file into an array

Assign Get-Content to a variable and you have an array of lines. Index it like any other array, and use -1 for the last line:

$lines = Get-Content -Path C:\psfaqs\servers.txt

"Lines:  $($lines.Count)"
"First:  $($lines[0])"
"Last:   $($lines[-1])"
"Second and third: $($lines[1..2] -join ', ')"

Output:

Lines:  4
First:  WEB01
Last:   FILE01
Second and third: WEB02, SQL01

The one-line file trap

If the file has only one line, Get-Content returns a single string instead of an array. Indexing a string gives you letters:

$lines = Get-Content -Path C:\psfaqs\one-line.txt
"Without @(): first = [$($lines[0])], rest = [$($lines[1..($lines.Count - 1)] -join ', ')]"

$lines = @(Get-Content -Path C:\psfaqs\one-line.txt)
"With @():    first = [$($lines[0])], rest = [$(($lines | Select-Object -Skip 1) -join ', ')]"

Output:

Without @(): first = [A], rest = [u, A]
With @():    first = [Austin], rest = []
PowerShell one-line file returns a string so [0] gives the first letter
A one-line file breaks array indexing until you add @() (Windows PowerShell 5.1)

$lines[0] returned the letter A, and the range 1..0 counted backwards through the letters. Wrapping Get-Content in @() keeps it an array, and Select-Object -Skip is safer than a range.

Read the first or last line

-TotalCount reads only the first lines and stops, and -Tail reads from the end of the file:

"First line: $(Get-Content -Path C:\psfaqs\servers.txt -TotalCount 1)"
"Last line:  $(Get-Content -Path C:\psfaqs\servers.txt -Tail 1)"
"Last two:   $((Get-Content -Path C:\psfaqs\servers.txt -Tail 2) -join ', ')"

Output:

First line: WEB01
Last line:  FILE01
Last two:   SQL01, FILE01

Both are faster than reading the whole file on big logs. The Get-Content documentation lists their aliases, -First and -Last.

Skip the first line

To skip a header row, pipe the lines to Select-Object -Skip 1:

Get-Content -Path C:\psfaqs\states.csv | Select-Object -Skip 1

Output:

California,39538223
Texas,29145505
Florida,21538187
Ohio,11799448

For CSV files, you usually don’t need to skip the header yourself. Import-Csv uses it to name the columns:

$rows = Import-Csv -Path C:\psfaqs\states.csv

"First row: $(($rows | Select-Object -First 1).State)"
"Last row:  $(($rows | Select-Object -Last 1).State)"

Output:

First row: California
Last row:  Ohio

Looping through CSV rows covers Import-Csv in more detail.

Why do special characters look wrong in Windows PowerShell 5.1?

cafe.txt is saved as UTF-8 without a byte order mark, which is how most editors and Linux tools save text today. Here’s how each version reads it:

"Default:        $(Get-Content -Path C:\psfaqs\cafe.txt)"
"-Encoding UTF8: $(Get-Content -Path C:\psfaqs\cafe.txt -Encoding UTF8)"

Output in PowerShell 7:

Default:        Café in San José
-Encoding UTF8: Café in San José

Output in Windows PowerShell 5.1:

Default:        Café in San José
-Encoding UTF8: Café in San José
PowerShell 5.1 Get-Content misreads UTF-8 without -Encoding UTF8
The accented letters break unless you add -Encoding UTF8 (Windows PowerShell 5.1)

Windows PowerShell 5.1 assumes the older Windows code page when there’s no byte order mark, so é turns into two wrong characters. Add -Encoding UTF8 in 5.1. PowerShell 7 reads UTF-8 by default.

Reading very large files

Get-Content is fine for most files, but it’s slow on files with hundreds of thousands of lines. [System.IO.File]::ReadLines() reads one line at a time and is much faster:

foreach ($line in [System.IO.File]::ReadLines('C:\Logs\big.log')) {
    if ($line -like '*ERROR*') { $line }
}

Give ReadLines a full path. Counting lines in a file has timing results for these methods on a 300,000-line log.

Frequently Asked Questions

How do I read a file line by line in PowerShell?

Use foreach ($line in Get-Content -Path file.txt) { ... }. Get-Content returns each line as a separate string.

How do I read only the first line of a file?

Use Get-Content -Path file.txt -TotalCount 1. It stops reading after the first line. Use -Tail 1 for the last line.

How do I skip the first line of a file in PowerShell?

Pipe it to Select-Object: Get-Content file.txt | Select-Object -Skip 1.

Why does $lines[0] return only one letter?

The file has one line, so Get-Content returned a string, not an array. Use $lines = @(Get-Content file.txt).

How do I get the line number while reading a file?

Use the ReadCount property of each line: Get-Content file.txt | ForEach-Object { "$($_.ReadCount): $_" }.

Once you can read a file, these are natural next steps:

  • Count lines in a file
  • Find a string in a file and return the line
  • Loop through CSV rows
  • Append to a file with Add-Content
Bijay Kumar
Bijay Kumar

Bijay Kumar is an esteemed author and the mind behind PowerShellFAQs.com, where he shares his extensive knowledge and expertise in PowerShell, with a particular focus on SharePoint projects. Recognized for his contributions to the tech community, Bijay has been honored with the prestigious Microsoft MVP award. With over 15 years of experience in the software industry, he has a rich professional background, having worked with industry giants such as HP and TCS. His insights and guidance have made him a respected figure in the world of software development and administration. Read more.

Follow us on X

Recent Posts

  • How to Convert XML to Excel Using PowerShell
  • How to Convert PDF to Word Using PowerShell?
  • How to Convert PNG to ICO Using PowerShell
  • Windows Terminal vs PowerShell: Which One to Use
  • How to Get Folder Size in PowerShell (Including Subfolders)
  • About
  • Contact
  • Privacy Policy
© 2026 PowerShellFAQs.com
100
PowerShell
Cmdlets
PowerShellFAQs.com PDF

Free PDF ebook

Where should I send your ebook?

Enter your details and the free 100 PowerShell Cmdlets PDF is on its way.

No spam. You'll also get new PowerShell tutorials by email. Unsubscribe anytime. Privacy policy

Check your inbox

Your free 100 PowerShell Cmdlets ebook is on its way to . Can't find it in a few minutes? Look in your Promotions or Spam folder.