How to Read from Text File in PowerShell

Problem

As engineer, it is common to have a task where we have to read from a text file. To automate this task, we can use PowerShell.

In this blog post, we will walk you through how to read from a text file in PowerShell.

Solution

In this context, we will read 5000 lines of Hello World! phrases from a text file named Book1.txt.

The content of the file will look as follows:

file content to be read

Using Get-Content Cmdlet

We can use PowerShell Get-Content cmdlet to get the content of text file, then read the content line by line.


$content = Get-Content "C:\temp\Book1.txt"

$counter = 0;
foreach ($line in $content)
{
    $counter++;
}

Write-Host $counter

Using ReadLines Method from .NET Framework

We can use ReadLines method from System.IO.File class in .NET Framework to get the content of the text file. Then, we will be able to process each of the line.


$path = "C:\temp\Book1.txt";

$counter = 0;
foreach ($line in [System.IO.File]::ReadLines($path)) {
    $counter++;
}

Write-Host $counter

Using OpenText and ReadLine Method from .NET Framework

Since PowerShell has access to .NET Framework libraries and classes, we can use some classes like File from System.IO namespace to read the file.

In the following example, we use OpenText method to open the text file and stream the content to be read. While reading the content line by line, we will count total number of lines in the file. Later we will display the number which is 5000.


using namespace System.IO

$path = "C:\temp\Book1.txt";

try {
    $sr = [File]::OpenText($path)

    $counter = 0;
    while ($null -ne ($str = $sr.ReadLine())) {
        $counter++;
    }

    Write-Host $counter
}
finally {
    <#Do this after the try block regardless of whether an exception occurred or not#>
    $sr.Dispose();
}

To work with File in .NET, we have to apply dispose pattern that can be achieved through try-finally block or using statement.

Since PowerShell doesn’t have the latter option, we will use only the former option where Dispose method will be invoked in finally block to release the resource.

We have to do this because finally block must be executed whether the exception/error occurs in the try block. So, we can ensure that the resource must be released.

If we don’t apply dispose pattern, memory leak will occur where eventually we will get OutOfMemoryException.

Emulate C# Using Statement

We know from previous example that PowerShell doesn’t have C# using statement that will ensure the object is disposed if exception occurs within using statement block.

However, we can create a function to emulate C# using statement by utilizing PowerShell script block. The function can be declared separately so that it can be imported in other files to make it modular or declared within the same file with the script that will use it.

In the following example, the function name is Use-Object. To use it, we enclose StreamReader object inside Use-Object and other statements to read the file inside curly brackets {}. If exception occurs, the object will be automatically released/disposed by finally block inside Use-Object function.


using namespace System.IO

function Use-Object {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory = $true)]
        [AllowEmptyString()]
        [AllowEmptyCollection()]
        [AllowNull()]
        [Object]
        $InputObject,

        [Parameter(Mandatory = $true)]
        [scriptblock]
        $ScriptBlock
    )

    try {
        . $ScriptBlock
    }
    finally {
        if ($null -ne $InputObject -and $InputObject -is [System.IDisposable]) {
            $InputObject.Dispose()
        }
    }
}

$path = "C:\temp\Book1.txt";

Use-Object ($sr = [File]::OpenText($path)) {
    $counter = 0;
    while ($null -ne ($str = $sr.ReadLine())) {
        $counter++;
    }

    Write-Host $counter
}

Conclusion

We can use Get-Content cmdlet to get the content of the text file then read each line. We can also utilize .NET Framework to do file processing in PowerShell. For reading the file especially text file (.txt), we can use some classes and methods from System.IO namespace.

We must also remember to implement dispose pattern when working with File processing in .NET Framework to avoid memory leak. Alternatively, we can emulate C# using statement that will automatically dispose the object by using PowerShell script block.