PowerShell 7.x FileSystem provider; Tail is also available in Windows PowerShell 5.1. Read permission on the file is required.
Stuart Kerr Spindlow has confirmed personal use and testing of the software covered by Happy SysAdm. The assessments here distinguish documented behaviour from measured results; worked scenarios are labelled and are not personal test records.Choose a question and a bounded read
For an error-string investigation, Select-String against the file is the most direct choice: its match records retain the source path and line number. Get-Content -Tail is preferable when the question is what happened most recently. Reading the entire file with -Raw is justified when a parser needs one complete string, but adds unnecessary scope to a simple tail or literal search. The bounded timing check below also favours direct file search for its specific fixture; the general recommendation remains to match the command to the question.
Start with a time window, event identifier or literal error string. For a recent failure, the final few hundred lines may be enough. Tail returns lines from the end; TotalCount limits a read from the beginning. Neither tells you that the file contains a complete incident history. Rotation may have moved the relevant period into another file.
Work on an approved copy when a producer locks the file or when an investigation requires preserved evidence. Note the path, size, timestamp and encoding. A log may contain personal data or secrets, so keep the copy in an access-controlled location.
Inspect and search without retaining everything
The first example shows a bounded tail. The second searches a file for a literal string. Change the illustrative path and search term for your environment. Select-String returns match records, so retain their path and line number when recording evidence.
Avoid assigning all lines of a large file to a variable and avoid Get-Content -Raw when you only need a few matches. Raw intentionally creates one string containing the file. Memory use also depends on line length, downstream commands and how many results you collect; a pipeline does not guarantee a fixed memory ceiling.
Get-Content -LiteralPath 'C:\Logs\service.log' -Tail 200
Select-String -LiteralPath 'C:\Logs\service.log' -Pattern 'timeout' -SimpleMatchHandle encoding, batching and live files
If characters are garbled, establish the writer’s encoding and use a matching Encoding value supported by your shell. Windows PowerShell and PowerShell 7 have different default encoding behaviours; do not assume the same output across both. Get-Content -Wait can follow additions to a file, but rotation and replacement need separate handling. Stop the follow with Ctrl+C.
ReadCount groups lines passed down the pipeline. Code expecting one string may receive an array instead, changing filtering behaviour. Benchmark a representative copy before adopting batching. Do not present a faster result from a tiny cached file as evidence about multi-gigabyte production logs.
Interpret an empty or incomplete result
No match may mean the wrong case-sensitive option, encoding, path, time zone or rotated file, rather than absence of a fault. Check a known event first. Multi-line records may need parsing beyond line matching.
Keep your evidence small: relevant lines, adjacent context, source path and capture time. If you redact a copy, preserve the original under the incident retention rules. Compare timestamps with the application and monitoring records before deciding on remediation.
What the 200-line example actually measures
The example requests at most 200 trailing lines; it does not read 200 bytes or guarantee a particular memory footprint. In a hypothetical one-million-line file, 200 lines are 0.02% of the line count. That arithmetic describes the requested output only: long lines, encoding, filesystem behaviour and downstream processing prevent a corresponding claim of 99.98% less runtime or memory.
Count matching lines separately from occurrences. A line containing the same word twice can still produce one match record. A defensible speed comparison would use the same file bytes, encoding, search semantics, PowerShell version and cache conditions. A local result does not establish the same difference for Windows, a multi-gigabyte log or a different output requirement.
A measured search on a synthetic log
On 23 September 2026, Codex ran PowerShell 7.6.6 on an Apple Silicon Mac with macOS 26.6.2 against one 100,000-line ASCII log of 12,800,000 bytes. The literal string ERROR appeared on 1,000 lines. Both direct Select-String file search and Get-Content piped into Select-String returned all 1,000 matching lines in every measured trial. After one warm-up per method, five alternating trials gave median elapsed times of 18.98 ms for direct search and 156.97 ms for the pipeline.
Direct-search times ranged from 18.50 to 117.75 ms; pipeline times ranged from 152.48 to 497.11 ms. The variation matters. Timing excluded PowerShell startup, caches were not flushed and peak memory was not measured. This single AI-run check supports direct search for this literal-search fixture; it is not Stuart’s personal benchmark or a transferable speed ratio for production logs. Get-Content -Tail 200 was also checked and returned exactly the final 200 lines.
| Method | Trials after warm-up | Median elapsed | Matching lines per trial |
|---|---|---|---|
| Select-String directly against the file | 5 | 18.98 ms | 1,000 |
| Get-Content piped into Select-String | 5 | 156.97 ms | 1,000 |
Use the right reader for Windows event logs
These text-file examples are not an EVTX parser. For the System or Application channel, or a saved .evtx file, use Get-WinEvent with a channel or Path filter. Keep the incident time window consistent when correlating Windows events with the text log.
The linked guide explains time, provider and event-ID filters, message searching and why a capped result is not a complete incident history. Preserve the existing plain-text search evidence separately from the Windows event record.