File System and Registry
Reviewed & published by Brayan K
By the end of this lesson you'll be able to list, create, copy, move, rename, read, write, and safely delete files and folders from PowerShell — the everyday skills that make the shell faster than clicking around in File Explorer.
Part of the free PowerShell course at LearnCodingFast — hands-on lessons with worked examples and the output they print, plus practice exercises and a quick quiz.
What You'll Learn
- List folder contents with Get-ChildItem (gci / ls) and move around with Set-Location (cd)
- Create files and folders with New-Item using -ItemType
- Copy, move, and rename with Copy-Item and Move-Item
- Read and write file content with Get-Content, Set-Content, and Add-Content
- Check a path safely with Test-Path before you act on it
- Delete safely: preview with -WhatIf before using Remove-Item -Recurse
💡 Real-World Analogy
Think of PowerShell as a universal remote control for storage. A normal remote only works with one TV; PowerShell's remote works with any device that speaks the same protocol. That protocol is the provider model: the file system, the Windows Registry, environment variables and certificates are all exposed as lettered "drives" (C:, HKCU:, Env:, Cert:). Because they all share one interface, the same verbs — Get-ChildItem, Set-Location, New-Item, Remove-Item — drive every one of them. Learn the buttons once and they work everywhere.
1. The Provider Model
A provider is an adapter that makes some data store look like a disk drive, so you can browse it with file-style commands. Get-PSProvider lists the adapters; Get-PSDrive lists the drives they expose. The big payoff: once you learn the file-system cmdlets below, the exact same commands also work on the registry and environment variables — you just point them at a different drive.
# A "provider" exposes some data store as if it were a disk drive.
# Get-PSProvider lists them; Get-PSDrive lists the drives they expose.
Get-PSProvider | Select-Object Name, Drives
# Because the FileSystem and Registry are BOTH providers, the SAME
# commands work on each — you just point them at a different drive.
Set-Location C:\ # move into the C: file-system drive
Set-Location HKCU:\ # move into the registry "current user" drive (Windows)2. Listing & Navigating
Get-ChildItem shows what's inside a folder — its aliases gci, ls and dir all run the same cmdlet, so use whichever feels natural. Set-Location (alias cd) moves you into a folder, and Get-Location (alias pwd) tells you where you are. Add -Recurse to dig into every sub-folder and -Filter to match a name pattern.
# Get-ChildItem lists what's inside a folder. Aliases: gci, ls, dir.
Get-ChildItem -Path C:\Projects
# Set-Location changes the current folder. Aliases: cd, sl.
Set-Location C:\Projects\my-app
Get-Location # where am I now? (alias: pwd)
# -Recurse digs into sub-folders; -Filter narrows by name pattern.
Get-ChildItem -Path C:\Projects -Recurse -Filter "*.log"3. Create, Copy, Move & Check
New-Item makes both files and folders — the -ItemType switch decides which. Copy-Item duplicates a file; Move-Item relocates it, and when the destination is just a new name in the same folder it acts as a rename (so you rarely need Rename-Item). Test-Path returns a plain True or False, which makes it perfect for an if check before you create or delete anything.
# New-Item makes files OR folders — choose with -ItemType.
New-Item -ItemType Directory -Path ".\reports" # a new folder
New-Item -ItemType File -Path ".\reports\june.txt" # an empty file
# Copy-Item duplicates; Move-Item moves OR renames (no separate Rename needed).
Copy-Item ".\reports\june.txt" ".\reports\june-backup.txt"
Move-Item ".\reports\june.txt" ".\reports\2026-june.txt" # this is a rename
# Test-Path returns a plain True/False — perfect for an "if".
Test-Path ".\reports\2026-june.txt"Now you try. The script below is almost complete — fill in the three blanks marked ___ using the hints in the comments, then run it and check your output against the expected lines.
# 🎯 YOUR TURN — replace each ___ then run it in PowerShell.
# 1) Create a folder called "notes" in the current directory
New-Item -ItemType ___ -Path ".\notes" # 👉 Directory or File?
# 2) Write a first line into notes\todo.txt (this also CREATES the file)
Set-Content -Path ".\notes\todo.txt" -Value ___ # 👉 some "text in quotes"
# 3) Append a second line to the same file
___ -Path ".\notes\todo.txt" -Value "Walk the dog" # 👉 which cmdlet APPENDS?
# Already wired up — reads the file back once your lines work:
Get-Content ".\notes\todo.txt"
# ✅ Expected output (if line 2 was "Buy milk"):
# Buy milk
# Walk the dog4. Reading & Writing File Content
Three cmdlets cover almost everything: Set-Content writes the file (replacing whatever was there), Add-Content appends a new line to the end, and Get-Content reads it back. One thing surprises everyone: Get-Content returns an array of lines, not a single block of text — so (Get-Content file).Count is the line count and [0] is the first line.
# Set-Content WRITES (and overwrites) the whole file.
Set-Content -Path ".\reports\log.txt" -Value "Service started"
# Add-Content APPENDS a new line to the end.
Add-Content -Path ".\reports\log.txt" -Value "Request handled"
Add-Content -Path ".\reports\log.txt" -Value "Service stopped"
# Get-Content READS the file. It returns an ARRAY: one item per line.
Get-Content -Path ".\reports\log.txt"
# So .Count is the number of lines, and [0] is the first line.
(Get-Content ".\reports\log.txt").Count # 3
(Get-Content ".\reports\log.txt")[0] # the first line5. Deleting — Safely
Remove-Item deletes files and folders. To remove a folder and its contents you must add -Recurse — and that is exactly where accidents happen, because there is no recycle bin to undo it. The safety habit: run the command first with -WhatIf, which prints every action it would take without changing a single byte on disk. When the preview looks right, run it again without -WhatIf.
# Remove-Item deletes. On a FOLDER you must add -Recurse to remove
# its contents too, otherwise PowerShell prompts you for confirmation.
# ALWAYS preview first with -WhatIf — it shows what WOULD happen,
# but changes nothing on disk.
Remove-Item ".\reports" -Recurse -WhatIf
# Happy with the preview? Run the real thing (drop -WhatIf).
Remove-Item ".\reports" -RecurseYour turn again. Guard the delete with Test-Path so it only runs when the folder exists, and preview it safely. Fill in the two blanks:
# 🎯 YOUR TURN — only delete the folder if it actually exists.
$folder = ".\notes"
# 1) Check whether the folder exists (returns True / False)
if (___ $folder) { # 👉 which cmdlet checks a path exists?
# 2) Preview the delete safely first — add the right switch
Remove-Item $folder -Recurse ___ # 👉 the "preview, change nothing" switch
Write-Output "Previewed delete of $folder"
} else {
Write-Output "Nothing to delete"
}
# ✅ Expected output (when .\notes exists):
# What if: Performing the operation "Remove Directory" on target "...\notes".
# Previewed delete of .\notesCommon Errors (and the fix)
- Deleting a whole tree by accident: Remove-Item .\folder -Recurse wipes everything inside with no undo. Fix: run it once with -WhatIf first to preview, then remove the switch.
- "A positional parameter cannot be found": usually a path with spaces that isn't quoted, so PowerShell splits it. Fix: quote the path — Get-Content "C:\My Reports\june.txt".
- Treating Get-Content as one string: it returns an array of lines, so string operations behave oddly. Fix: use [0] for the first line, .Count for the line count, or Get-Content -Raw for the whole file as one string.
- "Cannot remove item ... it is being used": the file is open in another program. Fix: close the program (or stop the process) holding the file, then retry.
- New-Item creates the wrong thing: leaving off -ItemType or mistyping it. Fix: be explicit — -ItemType File or -ItemType Directory.
Pro Tips
- 💡 Preview destructive commands with -WhatIf; PowerShell supports it on Remove-Item, Move-Item, Copy-Item and more.
- 💡 Quote every path. It costs nothing and saves you the day a folder has a space in its name.
- 💡 Live-tail a log with Get-Content app.log -Wait — it's PowerShell's tail -f.
- 💡 Pipe into Select-String to grep through files: Get-ChildItem -Recurse -Filter *.ps1 | Select-String "TODO".
📋 Quick Reference
| Task | Cmdlet (alias) | Example |
|---|---|---|
| List a folder | Get-ChildItem (ls) | Get-ChildItem C:\Projects |
| Change folder | Set-Location (cd) | Set-Location .\reports |
| New folder | New-Item -ItemType Directory | New-Item -ItemType Directory -Path .\logs |
| New file | New-Item -ItemType File | New-Item -ItemType File -Path a.txt |
| Copy / Move / Rename | Copy-Item / Move-Item | Move-Item a.txt b.txt |
| Write / Append / Read | Set- / Add- / Get-Content | Add-Content log.txt "line" |
| Path exists? | Test-Path | Test-Path .\logs |
| Delete (preview first!) | Remove-Item -Recurse -WhatIf | Remove-Item .\logs -Recurse -WhatIf |
Mini-Challenge: a Daily Log Tool
No blanks this time — just a brief and an outline to keep you on track. Build it, run it, and check the result against the comment. This is exactly the kind of small script that automates a real chore.
# 🎯 MINI-CHALLENGE: a tiny "daily log" tool
# 1. Make a folder ".\daily" (use New-Item -ItemType Directory).
# 2. Write today's date as the first line of ".\daily\entries.txt"
# (use Set-Content with (Get-Date).ToString("yyyy-MM-dd") ).
# 3. Append two log lines with Add-Content.
# 4. Print how many lines the file now has
# (hint: wrap Get-Content in parentheses, then .Count).
# 5. SAFETY: preview deleting the folder with Remove-Item ... -Recurse -WhatIf
#
# ✅ Expected (after 3 lines written): the number 3
# your code here🎉 Lesson Complete!
- ✅ One set of cmdlets works across every provider drive (C:, HKCU:, Env:)
- ✅ Get-ChildItem lists, Set-Location navigates, Get-Location tells you where you are
- ✅ New-Item -ItemType creates files or folders; Copy-Item/Move-Item duplicate, move and rename
- ✅ Set-Content writes, Add-Content appends, Get-Content reads (as an array of lines)
- ✅ Test-Path guards your actions; Remove-Item -Recurse deletes — always preview with -WhatIf first
Practice quiz
What is a PowerShell provider?
- An adapter that exposes a data store as a drive
- A type of variable
- A remote server
- A kind of loop
Answer: An adapter that exposes a data store as a drive. Providers expose stores like FileSystem and Registry as lettered drives.
Which cmdlet lists the contents of a folder?
- Show-Folder
- Get-ChildItem
- List-Items
- Read-Directory
Answer: Get-ChildItem. Get-ChildItem (aliases gci, ls, dir) lists what is inside a folder.
Which cmdlet changes your current location, like cd?
- Move-Path
- Go-Folder
- Set-Location
- Change-Dir
Answer: Set-Location. Set-Location (alias cd) changes the current working folder.
How do you create a new folder with New-Item?
- New-Item -Folder
- New-Item -Type Dir
- New-Item -Make
- New-Item -ItemType Directory
Answer: New-Item -ItemType Directory. New-Item -ItemType Directory creates a folder; -ItemType File creates a file.
Which cmdlet appends a line to the end of a file?
- Add-Content
- Set-Content
- Get-Content
- Push-Content
Answer: Add-Content. Add-Content appends; Set-Content overwrites the whole file.
What does Get-Content return for a multi-line text file?
- A single string
- An array of lines (one per line)
- A hashtable
- Nothing
Answer: An array of lines (one per line). Get-Content returns an array with one element per line.
Which cmdlet returns True or False for whether a path exists?
- Check-Path
- Exists-Item
- Test-Path
- Find-Path
Answer: Test-Path. Test-Path returns a Boolean, ideal for an if guard before acting.
What does the -WhatIf switch do on Remove-Item?
- Deletes faster
- Skips confirmation
- Recurses automatically
- Previews the action without changing anything
Answer: Previews the action without changing anything. -WhatIf shows what would happen but makes no changes on disk.
Which switch is required to delete a folder and its contents?
- -Recurse
- -Force
- -All
- -Deep
Answer: -Recurse. Remove-Item needs -Recurse to delete a folder along with everything inside.
Why should you quote file paths that contain spaces?
- It runs faster
- PowerShell would otherwise split the path at the space
- Quotes hide the path
- It is never necessary
Answer: PowerShell would otherwise split the path at the space. Without quotes PowerShell treats the space as a separator and misreads the path.
Continue this course
- Previous: Functions and Scripts
- Next: Automation and Task Scheduling — Schedule scripts with Task Scheduler, use WMI, and automate repetitive admin tasks
Frequently asked questions
What's the difference between New-Item -ItemType File and Directory?
Both use the same cmdlet; the -ItemType switch decides what gets created. -ItemType File makes an empty file at the path, and -ItemType Directory makes a folder. Forgetting -ItemType (or getting it wrong) is the most common New-Item mistake.
How do I rename a file in PowerShell?
Use Rename-Item for a pure rename in place, e.g. Rename-Item old.txt new.txt. Move-Item also renames when the destination is a new name in the same folder, so Move-Item old.txt new.txt does the same thing. Both work; Rename-Item reads more clearly.
Why does Get-Content give me an array instead of one string?
Get-Content reads a text file line by line and returns an array with one element per line. That means (Get-Content file).Count is the line count and [0] is the first line. If you genuinely need the whole file as a single string, use Get-Content -Raw.
Is Remove-Item -Recurse dangerous?
Yes — -Recurse deletes a folder and everything inside it, and there is no recycle bin for it. Always run the command once with -WhatIf first: it prints exactly what would be removed but changes nothing. Only when the preview looks right should you drop -WhatIf.
Do I really need quotes around paths?
You need quotes whenever a path contains spaces, e.g. "C:\My Reports\june.txt". Without quotes PowerShell treats the space as a separator and reads "C:\My" as the path. Quoting every path is a safe habit even when there are no spaces.