How to use PowerShell Get-Content to Read a File

The Get-Content cmdlet can be used to retrieve the contents from a file in PowerShell. It will retrieve the contents one line at a time, storing them in an array. This allows you to use or process each line in your PowerShell script.

Get-Content comes with several parameters that allow you to select or filter the results you want to retrieve from the file. And when you need to process a lot of large files, then using the -raw parameter can speed up the process.

In this article, we are going to take a look at how to use the Get-Content cmdlet, and explain the different parameters that we can use.

Read File with Get-Content

We are going to start with the basics, read a file in PowerShell line-by-line using the Get-Content cmdlet. For the examples below I will be using a text file with 100 lines, which are numbered. This makes it easier to follow the examples:

1..100 | ForEach-Object { Add-Content -Path .\LineNumbers.txt -Value "This is line $_." }

The code above is from Microsoft and creates a text file where each line starts with the string “This is line ” followed by the line number:

PowerShell Get-Content

To view the results of the newly created file, we can use the Get-Content cmdlet. You only need to specify the path to the file to start reading its contents of it:

Get-Content -Path .\LineNumbers.txt

If we store the result of Get-Content in a variable, then we can see that PowerShell stores the results in an array. This means that we can use any Array function on the results, or process each line using a ForEach loop:

$contents = Get-Content -Path .\LineNumbers.txt
$contents.GetType()

# Result 
IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Object[]                                 System.Array

# Return the 6th line (the index of an array start at 0 😉 )
$contents[5]

# Result
This is line 6
Read file contents with PowerShell
Using a ForEach loop on the Get-Contents result

Returning the First or Last x Lines

By default, the Get-Content cmdlet will return all the contents of a file in PowerShell. But in some cases, you only want to view the first or last x lines from a file. For example, when debugging an issue, you often only need the last couple of lines from a log file.

For this we have two options, we can use the parameter -TotalCount, which returns the first x items of the content. Or we can use the parameter -Tail, which returns the last x items of a file.

So let’s go back to our log file example. We want to view the last 10 lines from the log. To do this, we need to specify the path and add -Tail 10 to return only the last 10 lines:

Get-Content C:\temp\files\la-srv-dc01.log -Tail 10
PowerShell Get-Content return last x lines
Get-Content return the last x lines

To read the first x item from a file we will need to use the parameter -TotalCount:

Get-Content -Path .\LineNumbers.txt -TotalCount 5

Return a single line from a file

If you know which specific line you need from a text file, then it’s possible to select only a single line from the text file. As we know, the results are stored in an array. So we can use the array index to select a line number that we need.

Keep in mind that the array index starts at 0, so if we want to return line 16, we need to specify index number 15. We wrap the Get-Content command in parentheses ( ) so that PowerShell first completes the Get-Content command before it continues.

(Get-Content -Path .\LineNumbers.txt)[15]

# Result
This is line 16.

If you have a large text file then you might not want to read it completely to only return a single line. What you can do is select only the first or last x lines from the file, and then select the line number using the array index.

For example, let’s say we need the fifth line from a file. We set the TotalCount to 5, reading only the first 5 lines, and return the last item from the array:

(Get-Content -Path .\LineNumbers.txt -TotalCount 5)[-1]

# Result
This is line 5.

Reading Multiple Files with Get-Content

It’s also possible to read the contents of multiple files at once with Get-Content in PowerShell. To do this you only need to specify the path where the files are located followed by an asterisk *.

Get-Content -Path c:\temp\files\*

Keep in mind though that there won’t be any reference in the results to the source files. So you won’t know from which file line x comes.

We can also filter which files we want to read. So for example, if you only want to get the contents of all the .log files then you can add the parameter -Filter to it:

Get-Content -Path c:\temp\files\* -Filter '*.log'

Using -Raw

The Get-Content cmdlet reads each line of the file into the array, which is great when you need to process each line independently or you are looking for a single line. But array a terrible if you need to do a search and replace on the contents of a file.

For example, when you have an HTML file that you are using as a template for an email that you are about the send with PowerShell. In the HTML file, we have placeholders that we need to replace, like this:

<p>Hi {{manager.firstname}},</p>
<p>
 The account for {{user.fullname}} is ready. Below you will find the login details for {{user.firstname}}. We have set a temporary password which must be
 changed after the first login.
</p>
<p>
 In the attachment you will find a starting guide for new users
</p>

Instead of looping through each line to find the placeholders and replace them, we can use the -Raw parameter to read the whole file as a single string and use the -Replace operator to replace the placeholders:

(Get-Content -Path c:\temp\template.html -Raw) -replace '{{user.fullname}}', $user.fullName -replace '{{user.firstname}}', $user.givenName

Another advantage of using the -Raw parameter is that it’s a lot faster. Get-Content works great with small text files, but when you need to process large text files then you will probably notice that the command is a bit sluggish.

For example, a text file of 50Mb takes almost 5 seconds to read as you can see in the screenshot below:

Read large file with PowerShell

But when using -Raw it took less than half a second:

If you still need the results in an array then we can use -Raw combined with the -split string operator to create an array of each line of the file. This method is still 5 times faster than using Get-Content without -Raw.

$log = (Get-Content .\largefile.log -Raw) -split "`r`n"

Reading files faster with ReadAllLines

When processing very large files, 100Mb and large, then there is an even faster method to read the contents of the file with PowerShell. The .Net method System.IO.File.ReadAllLines(). will read all the lines into the memory in half of the time compared to using the -Raw method.

The results are, just like with Get-Content, stored in an array. So you can process that data in the same way.

$log = [System.IO.File]::ReadAllLines('c:\temp\files\largefile.log')

You can also use the method [System.IO.File]::ReadLines, which is even faster. But this will immediately stream the contents to the console, instead of storing it in the memory. The problem with this method is that you will need to close the file when done, otherwise, it will be locked by the stream.

Watch files with -Wait

The last interesting function of Get-Contents is that we can monitor or watch the contents of a file using the -Wait parameter. If you, for example, want to monitor a log file. Then instead of rerunning the Get-Content cmdlet every time, you can add the -wait parameter.

As soon as the contents of the file are updated (and saved), it will update the output of Get-Content.

Get-Content -Path c:\temp\testfiles\LineNumbers.txt -Tail 5 -Wait

# Result
This is line 96.
This is line 97.
This is line 98.
This is line 99.
This is line 100.

If we add new lines to the end of the file, then these will show up in the results.

Wrapping Up

The Get-Content cmdlet in PowerShell is great when you need to read a file quickly. But when working with large files you really need to use the -Raw parameter at least to speed up the process. Also, give the .Net method a try, you will be amazed at how fast it is.

I hope you found this article useful, if you have any questions, then just drop a comment below.

4 thoughts on “How to use PowerShell Get-Content to Read a File”

  1. I’m new to Powershell scripting and want to know what type of script this is and is there a way to see what the script is doing. I have a Powershell script to show you and if you can tell me what is doing. Thank you

    $secStringPassword = Get-RpsProtectedProperty -BaseEntity $cdnCertificate -Name Password
    [pscredential]$credObject = New-Object System.Management.Automation.PSCredential (‘NotUsed’, $secStringPassword)
    $secrets = $credObject.GetNetworkCredential().Password
    $importcdnCertificateCommand = “sudo pwsh -c ‘Import-Module -Name Rps-LinuxDsc; {0} = ConvertTo-SecureString -String {1} -AsplainText -Force; Import-RpsNxCertificate -Path {2} -Password {3}'” -f ‘$certificatePassword’, $secrets, $remoteTempCdnPath, ‘$certificatePassword’
    $result = Invoke-VMScript -VM $vm -ScriptText $importcdnCertificateCommand -GuestCredential $credential -ScriptType Bash
    Test-ScriptResult -Result $result

    • THe script imports a PowerShell module on a remove Linux VM, and is used to perform some certificate-related operations on the remote system. The outcome of the remote script execution is then tested using the Test-ScriptResult function.

  2. Hello,
    I have a quirk I can’t figure out and was hoping you might post the fixed code here for me. I’m getting data (no headers) from a TXT file and creating a new CSV file (no headers) with that data. However, I’m getting this warning:
    “WARNING: One or more headers were not specified. Default names starting with “H” have been used in place of any missing headers.”

    Original TXT data looks like this (notice 3 null columns):
    000000001|RICE|ANN||123 MAIN STREET|FL 18|FAKETOWN|ZZ|55555|20010911|F||(555)555-1212||A

    CSV data looks like this (notice H1, H2, H3):
    1 RICE ANN H1 123 MAIN STREET FL 18 FAKETOWN ZZ 55555 20010911 F H2 (555)555-1212 H3 A

    Thank you for your help, very much appreciated!

Leave a Comment

0 Shares
Tweet
Pin
Share
Share