get-childitem — PowerShell's directory-listing cmdlet — the ls equivalent across all 5 shells
Equivalents in every shell
ls -laPOSIX `ls` — pre-installed everywhere. `-l` is long format; `-a` includes dotfiles; `-h` is human-readable sizes; `-R` recurses. Output is text columns, parsed downstream by `awk` / `cut`. Note that parsing `ls` output is fragile — filenames with spaces/newlines break it; use `find` or `stat` for scripts.
ls -laSame `/bin/ls` binary. macOS BSD `ls` differs from GNU `ls`: `--color` (long form) works on GNU only; macOS uses `-G` for color. For recursive globs zsh has the elegant `print -l **/*.txt` (no `find` needed) — equivalent of PowerShell's `Get-ChildItem -Recurse -Filter *.txt`.
ls -laSame external. Fish has no built-in `ls` — uses the system `ls`. For recursive listing fish glob `**/*.txt` works similarly to zsh. Fish ships a slightly nicer default `ls` color scheme but the binary is identical.
Get-ChildItem -ForcePowerShell-native cmdlet (aliases `gci`, `ls`, `dir`). `-Force` includes hidden + system files (PowerShell HIDES them by default, unlike `ls -a`). `-Recurse` walks subdirectories; `-Filter` is provider-level + fast (`Get-ChildItem -Recurse -Filter *.log`); `-Include` is post-filter (works only with `-Recurse` or trailing `\*`). `-File` / `-Directory` filter by type (PS 3.0+, replaces legacy `?{ $_.PSIsContainer }`).
dir /s`/s` recurses; `/a` includes hidden/system files; `/b` is "bare" mode (just filenames, one per line — parseable). For PowerShell-like attribute filtering use `/ah` (hidden), `/ad` (directories), `/a-d` (files only). cmd `dir` is the legacy ancestor of `Get-ChildItem` — many flags overlap conceptually but not syntactically.
Worked examples
List all files including hidden, recursively
ls -laRGet-ChildItem -Recurse -Forcedir /s /aList only .log files, recursively
find . -name "*.log"Get-ChildItem -Recurse -Filter *.logdir /s /b *.logList only directories (no files)
ls -d */ls -d */Get-ChildItem -Directorydir /ad /bGotchas
- `Get-ChildItem -Recurse` does NOT follow symlinks on PowerShell 6+ (`-FollowSymlink` opt-in) — but DOES follow them on the Windows-bundled PS 5.1, which can cause infinite-loop traversals on cyclic links. Scripts that target both should use `-FollowSymlink` explicitly or fall back to `Get-ChildItem -Attributes !ReparsePoint`.
- `-Filter` and `-Include` are NOT interchangeable. `-Filter` is passed to the underlying filesystem provider (Win32 `FindFirstFile`), supports `*` and `?` only, and is FAST. `-Include` is PowerShell-side post-walk filtering, supports richer wildcards, and is SLOW on large trees. Use `-Filter` whenever possible.
- On pwsh Linux/macOS, the `ls` alias for `Get-ChildItem` is REMOVED so the system `/bin/ls` resolves first. Scripts using `ls -la` on pwsh Linux call the real `ls` and get bash-style output, not `Get-ChildItem` objects. On Windows pwsh, `ls` still resolves to the cmdlet — `ls -la` ERRORS because the cmdlet has no `-la` parameter.
- PowerShell HIDES hidden + system files by default — `Get-ChildItem` without `-Force` does NOT show dotfiles or `$RECYCLE.BIN`. This is the opposite of `ls` (which hides only with `-a`) but matches `cmd.exe dir` (which hides without `/a`).
- `-LiteralPath` is required for paths containing `[ ] *` (PowerShell wildcard chars). `Get-ChildItem "C:\My [Backup] Folder"` SILENTLY RETURNS NOTHING because `[Backup]` is a character class with no match; use `Get-ChildItem -LiteralPath "C:\My [Backup] Folder"`. Same trap as `Remove-Item`.
WSL & PowerShell Core notes
Common tasks using get-childitem
- Find broken symlinks
List symlinks whose target no longer exists — useful for post-uninstall cleanup, package-manager state, and orphaned-dotfile detection.
- Find files larger than 100MB
List files exceeding a size threshold — useful for cleanup, quota enforcement, and identifying log-rotation gaps.
- List empty directories
Find directories with no files — useful for cleanup, build-output verification, and detecting failed extractions.