💡PowerShell Tip for Large Files – The Get-Content -Tail and -Wait parameters
In PowerShell, you can display the last *n* lines of large text or ASCII files using the `-Tail` parameter of the `Get-Content` cmdlet:
In Powershell, you can display the last *n* lines of large tyt or ASCII files using the -Tail parameter of the Get-Content cmdlet:
<code>Get-Content meineRiesigeDatei.csv -tail 25</code>Since PowerShell version 3, Get-Content (or its alias gc) includes the -Tail parameter. Unfortunately, there is no built-in equivalent to the Unix tail -f command for continuous updates.
PowerShell: Get-Content with -Wait
PowerShell’s Get-Content cmdlet supports the -Wait parameter, which continuously monitors a file for new content:
Get-Content -Path "C:\path\to\your\file.log" -Wait -Tail 10This will display new lines as they are appended to the file.
PowerShell with filtering (advanced usage)
If you want something closer to tail -f | grep:
Get-Content "C:\path\to\file.log" -Wait | Select-String "ERROR"Windows Subsystem for Linux (WSL)
If you’re already using WSL (which you mentioned earlier), just use the real thing:
tail -f /mnt/c/path/to/file.logThis is often the most predictable behavior, especially for large logs, but it can be tricky, if your are using mounted network drives. But that’s another story.
Using Git Bash / Cygwin
If you have Unix-like tooling installed:
- Git Bash (from Git for Windows)
- Cygwin
Then:
tail -f file.logPowerShell tail -f-like function
Here’s a reusable PowerShell function that behaves much closer to tail -f, including:
- continuous follow (
-Wait) - configurable initial tail
- file rotation handling (log recreated / truncated)
- optional filtering (like
grep) - resilient retry loop
function Tail-F {
param(
[Parameter(Mandatory=$true)]
[string]$Path,
[int]$Tail = 10,
[int]$PollIntervalMs = 1000,
[string]$Filter,
[switch]$ShowFileName
)
if (-not (Test-Path $Path)) {
Write-Warning "File not found. Waiting for creation: $Path"
while (-not (Test-Path $Path)) {
Start-Sleep -Milliseconds $PollIntervalMs
}
}
$lastLength = 0
while ($true) {
try {
$file = Get-Item $Path -ErrorAction Stop
# Detect truncation or rotation
if ($file.Length -lt $lastLength) {
Write-Verbose "File truncated or rotated. Restarting..."
$lastLength = 0
}
$stream = [System.IO.File]::Open($Path, 'Open', 'Read', 'ReadWrite')
$reader = New-Object System.IO.StreamReader($stream)
if ($lastLength -eq 0 -and $Tail -gt 0) {
# Initial tail
$lines = Get-Content $Path -Tail $Tail
foreach ($line in $lines) {
if (-not $Filter -or $line -match $Filter) {
if ($ShowFileName) {
Write-Output "$Path`: $line"
} else {
Write-Output $line
}
}
}
$lastLength = $file.Length
} else {
# Continue from last position
$stream.Seek($lastLength, 'Begin') | Out-Null
while (-not $reader.EndOfStream) {
$line = $reader.ReadLine()
if (-not $Filter -or $line -match $Filter) {
if ($ShowFileName) {
Write-Output "$Path`: $line"
} else {
Write-Output $line
}
}
}
$lastLength = $stream.Position
}
$reader.Close()
$stream.Close()
}
catch {
Write-Warning "Error reading file. Retrying..."
}
Start-Sleep -Milliseconds $PollIntervalMs
}
}Usage examples
Basic follow (like tail -f)
Tail-F -Path "C:\logs\app.log"Show last 50 lines initially
Tail-F -Path "C:\logs\app.log" -Tail 50Filter like grep
Tail-F -Path "C:\logs\app.log" -Filter "ERROR|WARN"Debug multiple logs (with filename prefix)
Tail-F -Path "C:\logs\app.log" -ShowFileNameWhy this is better than Get-Content -Wait (IMHO)
Get-Content -Wait has limitations:
- struggles with log rotation
- can miss lines when files are truncated/recreated
- no built-in filtering
This function:
- reopens the file every cycle → handles rotation
- tracks byte position → efficient for large logs
- adds filtering inline
Make Tail-F permanently available
To make your Tail-F function permanently available in PowerShell, you should add it to your PowerShell profile ($PROFILE). That way it loads automatically in every session.
Locate your PowerShell profile
Run:
$PROFILETypical result (Windows PowerShell or PowerShell Core):
C:\Users\<your-user>\Documents\PowerShell\Microsoft.PowerShell_profile.ps12. Create the profile if it doesn’t exist
if (!(Test-Path $PROFILE)) {
New-Item -ItemType File -Path $PROFILE -Force
}3. Open the profile for editing
Example with Visual Studio Code:
code $PROFILEOr with Notepad:
notepad $PROFILE4. Add the Tail-F function
Paste your function at the end of the profile file. Save the file.
5. Reload your profile (without restarting shell)
. $PROFILE6. Verify
Get-Command Tail-FThen test:
Tail-F -Path "C:\temp\test.log"Practical notes (important)
- If you use both:
- Windows PowerShell (5.1)
- PowerShell 7+
$PROFILE | Format-List *