Skip to main content
    Courses/PowerShell/File System and Registry

    Lesson 5 • Beginner

    Working with Files & Folders 📁

    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.

    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.

    See the providers and their drives
    # 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)
    Output
    Name         Drives
    ----         ------
    Registry     {HKLM, HKCU}
    Alias        {Alias}
    Environment  {Env}
    FileSystem   {C, D, Temp}
    Function     {Function}
    Variable     {Variable}
    Certificate  {Cert}
    Run this in a PowerShell terminal (pwsh). The HKCU: registry drive is Windows-only.

    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.

    Worked example: list and move around
    # 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"
    Output
        Directory: C:\Projects
    
    Mode    LastWriteTime        Length Name
    ----    -------------        ------ ----
    d----   2026-06-10  09:14           my-app
    d----   2026-06-11  16:02           archive
    -a---   2026-06-12  08:30      482  notes.txt
    
    Path
    ----
    C:\Projects\my-app
    
        Directory: C:\Projects\my-app\logs
    
    Mode    LastWriteTime        Length Name
    ----    -------------        ------ ----
    -a---   2026-06-12  08:30      120  app.log
    Run this in a PowerShell terminal (pwsh). Your folders and timestamps will differ.

    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.

    Worked example: create, copy, move, test
    # 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"
    Output
        Directory: C:\Projects\my-app
    
    Mode    LastWriteTime        Length Name
    ----    -------------        ------ ----
    d----   2026-06-15  10:01           reports
    
        Directory: C:\Projects\my-app\reports
    
    Mode    LastWriteTime        Length Name
    ----    -------------        ------ ----
    -a---   2026-06-15  10:01        0  june.txt
    
    True
    Run this in a PowerShell terminal (pwsh) inside a throwaway folder.

    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: create and write a file
    # 🎯 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 dog
    Output
    Buy milk
    Walk the dog
    Replace each ___, run it, and match the expected output.

    4. 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.

    Worked example: write, append, read
    # 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 line
    Output
    Service started
    Request handled
    Service stopped
    3
    Service started
    Run this in a PowerShell terminal (pwsh) inside a throwaway folder.

    5. 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.

    Worked example: preview before you delete
    # 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" -Recurse
    Output
    What if: Performing the operation "Remove Directory" on target "C:\Projects\my-app\reports".
    What if: Performing the operation "Remove File" on target "C:\Projects\my-app\reports\log.txt".
    Run this in a PowerShell terminal (pwsh). With -WhatIf nothing is actually deleted.

    Your 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: guard a delete with Test-Path
    # 🎯 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 .\notes
    Output
    What if: Performing the operation "Remove Directory" on target "C:\Projects\my-app\notes".
    Previewed delete of .\notes
    Replace each ___, run it, and match the expected output.

    Common 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

    TaskCmdlet (alias)Example
    List a folderGet-ChildItem (ls)Get-ChildItem C:\\Projects
    Change folderSet-Location (cd)Set-Location .\\reports
    New folderNew-Item -ItemType DirectoryNew-Item -ItemType Directory -Path .\\logs
    New fileNew-Item -ItemType FileNew-Item -ItemType File -Path a.txt
    Copy / Move / RenameCopy-Item / Move-ItemMove-Item a.txt b.txt
    Write / Append / ReadSet- / Add- / Get-ContentAdd-Content log.txt "line"
    Path exists?Test-PathTest-Path .\\logs
    Delete (preview first!)Remove-Item -Recurse -WhatIfRemove-Item .\\logs -Recurse -WhatIf

    Frequently Asked Questions

    Q: 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.

    Q: 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.

    Q: 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.

    Q: 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.

    Q: 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.

    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: build a daily log
    # 🎯 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
    Output
    3
    Write it yourself, run it in PowerShell, and confirm it prints 3.

    🎉 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
    • Next lesson: Automation and Task Scheduling — run your scripts on a schedule

    Sign up for free to track which lessons you've completed and get learning reminders.

    Previous

    Cookie & Privacy Settings

    We use cookies to improve your experience, analyze traffic, and show personalized ads. You can manage your preferences below.

    By clicking "Accept All", you consent to our use of cookies for analytics and personalized advertising. You can customize your preferences or reject non-essential cookies.

    Privacy PolicyTerms of Service