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:
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
.