PowerShell Get-ChildItem: List Files and Folders (Full Guide)

PowerShell Get-ChildItem: List Files and Folders (Full Guide)

PowerShell Tips Editor 3 min read
PowerShell Get-ChildItem: List Files and Folders (Full Guide)

The old dir command shows you a text listing. PowerShell Get-ChildItem does something much more useful: it returns real file and folder objects with properties like Length, LastWriteTime, Extension, and FullName that you can filter, sort, and act on immediately. Whether you’re listing all .log files over a week old, finding hidden items, or recursing an entire directory tree, this guide covers every practical Get-ChildItem pattern you need.

Basic Get-ChildItem Usage

With no arguments, Get-ChildItem lists the current directory. Pass a path to list any location:

# List current directory
Get-ChildItem

# List a specific folder
Get-ChildItem -Path 'C:\Users\Public\Documents'

# Aliases: gci, ls, dir (all call Get-ChildItem)
ls C:\Logs
dir C:\Scripts

# Show full path info
Get-ChildItem C:\Logs | Select-Object FullName, Length, LastWriteTime
    Directory: C:\Logs

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a---           5/4/2026  9:15 AM          10240 app.log
-a---           5/4/2026  8:01 AM           4096 error.log
d----           5/3/2026 11:00 PM               Archive

The returned objects are System.IO.FileInfo (for files) and System.IO.DirectoryInfo (for folders). Files have a Length property; folders have a GetFiles() method.

Filtering by Extension with -Filter

-Filter is the fastest way to limit results to a specific pattern — it filters at the OS level before objects are created:

# List only .log files
Get-ChildItem -Path C:\Logs -Filter '*.log'

# List only .ps1 files
Get-ChildItem -Path C:\Scripts -Filter '*.ps1'

# Filter with specific prefix
Get-ChildItem -Path C:\Logs -Filter 'app_*.log'
Mode      LastWriteTime         Length Name
----      -------------         ------ ----
-a---     5/4/2026  9:15 AM      10240 app.log
-a---     5/4/2026  8:01 AM       4096 app_error.log

Important limitation: -Filter only accepts a single pattern. To match multiple patterns (e.g., both .log and .txt), use -Include instead — but note that -Include requires -Recurse or a path ending in \* to work correctly.

Recursive Search with -Recurse

Add -Recurse to search all subdirectories:

# All .log files in C:\Logs and all subfolders
Get-ChildItem -Path C:\Logs -Filter '*.log' -Recurse

# Count all files recursively
(Get-ChildItem -Path C:\Scripts -Recurse -File).Count

# Combined with Where-Object for complex filtering
Get-ChildItem -Path C:\Logs -Recurse -File |
    Where-Object { $_.LastWriteTime -lt (Get-Date).AddDays(-7) } |
    Select-Object FullName, LastWriteTime
    Directory: C:\Logs

Mode      LastWriteTime         Length Name
----      -------------         ------ ----
-a---     5/4/2026  9:15 AM      10240 app.log

    Directory: C:\Logs\Archive

Mode      LastWriteTime         Length Name
----      -------------         ------ ----
-a---     4/27/2026  2:00 PM      8192 app_old.log

On deep directory trees, -Recurse can be slow. Add -Filter or -Depth N to limit scope. -Depth 2 (PS5+) limits recursion to 2 levels deep.

Including Hidden and System Files

By default, Get-ChildItem skips hidden and system files. Use -Force to include them:

# Include hidden files
Get-ChildItem -Path C:\Users\Alice -Force

# Find hidden files specifically
Get-ChildItem -Path C:\Windows -Force -File |
    Where-Object { $_.Attributes -band [System.IO.FileAttributes]::Hidden }

# List all hidden folders in a directory
Get-ChildItem -Path C:\Users -Force |
    Where-Object { $_.PSIsContainer -and ($_.Attributes -band 2) }

Listing Only Files or Only Folders

Use -File or -Directory to restrict the type of items returned:

# List only files (no folders)
Get-ChildItem -Path C:\Logs -File

# List only folders (no files)
Get-ChildItem -Path C:\Users\Public -Directory

# Recursive file listing only
Get-ChildItem -Path C:\Scripts -Recurse -File | Select-Object FullName
FullName
--------
C:\Scripts\backup.ps1
C:\Scripts\cleanup.ps1
C:\Scripts\Helpers\utils.ps1

-File and -Directory are cleaner than Where-Object { -not $_.PSIsContainer } and filter at the cmdlet level.

Combining with Where-Object for Advanced Filtering

Get-ChildItem combined with Where-Object handles any filtering scenario:

# Files larger than 10MB modified in the last 30 days
Get-ChildItem -Path C:\Logs -Recurse -File | Where-Object {
    $_.Length -gt 10MB -and $_.LastWriteTime -gt (Get-Date).AddDays(-30)
} | Select-Object Name, @{ Name='SizeMB'; Expression={ [math]::Round($_.Length/1MB,1) } }, LastWriteTime

# Multiple extension filter (no -Filter limitation)
Get-ChildItem -Path C:\Users\Public\Documents -Recurse -File |
    Where-Object { $_.Extension -in @('.docx', '.xlsx', '.pdf') } |
    Sort-Object Length -Descending
Name        SizeMB LastWriteTime
----        ------ -------------
system.log    15.3 5/1/2026 2:00 AM
audit.log     12.7 4/30/2026 11:59 PM

Common Errors and Fixes

  • -Filter only takes one pattern — use -Include for multiple: Get-ChildItem -Filter '*.log','*.txt' does not work — -Filter is a single string. Use -Include @('*.log','*.txt') -Recurse for multiple patterns, or pipe to Where-Object { $_.Extension -in @('.log','.txt') }.
  • Recurse on deep trees is slow — filter early: Get-ChildItem C:\Windows -Recurse can return hundreds of thousands of items and take minutes. Always add -Filter, -Depth, or -ErrorAction SilentlyContinue to handle access-denied folders gracefully.

Related Cmdlets / See Also

Wrapping Up

Get-ChildItem returns file objects you can immediately filter, sort, and pipeline into other commands. Use -Filter for speed on single patterns, -Include for multiple patterns, -Recurse for subdirectory traversal, and -File/-Directory to focus on one type. Your next step: try finding all .log files older than 7 days in your log folder and see what you’d be able to clean up.

Send-Item -To