Working with Files and Folders

Master file system operations in PowerShell: creating, reading, writing, copying, moving, and deleting files and directories with practical examples.

📖 6 min read📅 2026-02-10Working with Data
# Current directory
Get-Location          # or: pwd
 
# Change directory
Set-Location "C:\Users"    # or: cd C:\Users
 
# Go back to previous location
Set-Location -          # or: cd -
 
# List directory contents
Get-ChildItem                # or: ls, dir
Get-ChildItem -Force         # Include hidden files
Get-ChildItem -Recurse       # List recursively
 
# Check if path exists
Test-Path "C:\Users"               # True
Test-Path "C:\nonexistent"         # False
Test-Path "C:\file.txt" -PathType Leaf       # Is it a file?
Test-Path "C:\Users" -PathType Container     # Is it a folder?

Creating Files and Folders

# Create a new directory
New-Item -Path "C:\Projects\MyApp" -ItemType Directory
# Shortcut:
mkdir "C:\Projects\MyApp"
 
# Create a new file
New-Item -Path "readme.txt" -ItemType File
New-Item -Path "config.json" -ItemType File -Value '{"key": "value"}'
 
# Create nested directories (creates parent folders too)
New-Item -Path "C:\Projects\MyApp\src\components" -ItemType Directory -Force
 
# Create multiple files at once
"index.html", "style.css", "app.js" | ForEach-Object {
    New-Item -Path "C:\Projects\MyApp\$_" -ItemType File
}

Reading Files

# Read entire file as an array of lines
$lines = Get-Content "data.txt"
$lines[0]     # First line
$lines[-1]    # Last line
$lines.Count  # Number of lines
 
# Read as a single string
$text = Get-Content "data.txt" -Raw
 
# Read first/last N lines
Get-Content "log.txt" -Head 10     # First 10 lines
Get-Content "log.txt" -Tail 20     # Last 20 lines
 
# Read with encoding
Get-Content "data.txt" -Encoding UTF8
 
# Read and filter
Get-Content "log.txt" | Where-Object { $_ -match "ERROR" }
 
# Monitor file in real-time (like tail -f)
Get-Content "log.txt" -Wait -Tail 10

Writing Files

# Write to file (overwrite)
"Hello, World!" | Out-File "output.txt"
Set-Content -Path "output.txt" -Value "Hello, World!"
 
# Append to file
"New line" | Out-File "output.txt" -Append
Add-Content -Path "output.txt" -Value "Appended line"
 
# Write multiple lines
$lines = @(
    "Line 1"
    "Line 2"
    "Line 3"
)
$lines | Out-File "output.txt"
 
# Write with encoding
"UTF-8 content" | Out-File "output.txt" -Encoding utf8
 
# Write objects to file
Get-Process | Out-File "processes.txt"
 
# Write CSV
Get-Process | Select-Object Name, CPU, WorkingSet |
    Export-Csv "processes.csv" -NoTypeInformation
 
# Write JSON
@{Name="Alice"; Age=30} | ConvertTo-Json | Out-File "data.json"

Copying Files and Folders

# Copy a file
Copy-Item "source.txt" -Destination "backup.txt"
 
# Copy to a directory
Copy-Item "report.pdf" -Destination "C:\Backup\"
 
# Copy directory and contents
Copy-Item "C:\Source\Folder" -Destination "C:\Backup\Folder" -Recurse
 
# Copy with filter
Copy-Item "C:\Source\*" -Destination "C:\Backup\" -Filter "*.log" -Recurse
 
# Copy multiple files
Copy-Item "file1.txt", "file2.txt", "file3.txt" -Destination "C:\Backup\"
 
# Copy and rename
Copy-Item "config.json" -Destination "config.backup.json"

Moving and Renaming

# Move a file
Move-Item "old-location\file.txt" -Destination "new-location\file.txt"
 
# Rename a file
Rename-Item "oldname.txt" -NewName "newname.txt"
 
# Rename with pattern
Get-ChildItem *.txt | Rename-Item -NewName { $_.Name -replace '\.txt$', '.md' }
 
# Move all files of a type
Get-ChildItem -Filter "*.log" | Move-Item -Destination "C:\Archives\"
 
# Bulk rename with counter
$counter = 1
Get-ChildItem *.jpg | ForEach-Object {
    Rename-Item $_.FullName -NewName "photo_$($counter.ToString('D3')).jpg"
    $counter++
}

Deleting Files and Folders

# Delete a file
Remove-Item "unwanted.txt"
 
# Delete with confirmation
Remove-Item "important.txt" -Confirm
 
# Delete a directory and all contents
Remove-Item "C:\Temp\OldProject" -Recurse -Force
 
# Delete files matching a pattern
Remove-Item *.tmp
Remove-Item *.log -Recurse
 
# Delete empty directories
Get-ChildItem -Directory -Recurse |
    Where-Object { (Get-ChildItem $_.FullName).Count -eq 0 } |
    Remove-Item
 
# Safe delete: move to recycle bin (requires shell)
Add-Type -AssemblyName Microsoft.VisualBasic
[Microsoft.VisualBasic.FileIO.FileSystem]::DeleteFile(
    "C:\file.txt",
    'OnlyErrorDialogs',
    'SendToRecycleBin'
)

File Properties and Information

# Get file info
$file = Get-Item "document.txt"
$file.Name              # "document.txt"
$file.Extension         # ".txt"
$file.Length             # Size in bytes
$file.FullName          # Full path
$file.DirectoryName     # Parent directory
$file.CreationTime      # When created
$file.LastWriteTime     # When last modified
$file.LastAccessTime    # When last accessed
$file.Attributes        # File attributes
 
# Get directory info
$dir = Get-Item "C:\Projects"
$dir.CreationTime
(Get-ChildItem $dir -Recurse -File).Count    # File count
(Get-ChildItem $dir -Recurse -File | Measure-Object -Property Length -Sum).Sum  # Total size
 
# Calculate folder size
function Get-FolderSize {
    param([string]$Path)
 
    $size = (Get-ChildItem $Path -Recurse -File -ErrorAction SilentlyContinue |
        Measure-Object -Property Length -Sum).Sum
 
    [PSCustomObject]@{
        Path   = $Path
        SizeMB = [math]::Round($size / 1MB, 2)
        SizeGB = [math]::Round($size / 1GB, 2)
    }
}
 
Get-FolderSize "C:\Users"

Searching for Files

# Find by name
Get-ChildItem -Path "C:\" -Filter "*.config" -Recurse -ErrorAction SilentlyContinue
 
# Find by content (grep equivalent)
Select-String -Path "C:\Logs\*.log" -Pattern "ERROR"
Select-String -Path "*.ps1" -Pattern "function" -Recurse
 
# Find large files
Get-ChildItem -Recurse -File |
    Where-Object { $_.Length -gt 100MB } |
    Sort-Object Length -Descending |
    Select-Object FullName, @{N="SizeMB"; E={[math]::Round($_.Length/1MB,2)}}
 
# Find recently modified files
Get-ChildItem -Recurse -File |
    Where-Object { $_.LastWriteTime -gt (Get-Date).AddDays(-7) } |
    Sort-Object LastWriteTime -Descending
 
# Find duplicate files by name
Get-ChildItem -Recurse -File |
    Group-Object Name |
    Where-Object { $_.Count -gt 1 }

Practical Example: File Organizer

function Organize-Downloads {
    param(
        [string]$SourcePath = "$HOME\Downloads",
        [switch]$WhatIf
    )
 
    $categories = @{
        Images    = @(".jpg", ".jpeg", ".png", ".gif", ".bmp", ".svg", ".webp")
        Documents = @(".pdf", ".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx", ".txt")
        Videos    = @(".mp4", ".avi", ".mkv", ".mov", ".wmv")
        Music     = @(".mp3", ".wav", ".flac", ".aac", ".ogg")
        Archives  = @(".zip", ".rar", ".7z", ".tar", ".gz")
        Code      = @(".py", ".js", ".ts", ".ps1", ".sh", ".java", ".cpp")
    }
 
    Get-ChildItem -Path $SourcePath -File | ForEach-Object {
        $file = $_
        $moved = $false
 
        foreach ($category in $categories.Keys) {
            if ($file.Extension.ToLower() -in $categories[$category]) {
                $destination = Join-Path $SourcePath $category
 
                if (-not (Test-Path $destination)) {
                    New-Item -Path $destination -ItemType Directory | Out-Null
                }
 
                if ($WhatIf) {
                    Write-Host "Would move: $($file.Name) -> $category/"
                }
                else {
                    Move-Item $file.FullName -Destination $destination
                    Write-Host "Moved: $($file.Name) -> $category/" -ForegroundColor Green
                }
 
                $moved = $true
                break
            }
        }
 
        if (-not $moved) {
            Write-Host "Skipped: $($file.Name) (no category)" -ForegroundColor Yellow
        }
    }
}
 
# Preview what would happen
Organize-Downloads -WhatIf
 
# Actually organize
Organize-Downloads

Exercises

  1. Write a script that backs up all .ps1 files from a folder to a dated backup folder
  2. Create a function that finds and removes all empty folders recursively
  3. Build a log rotation script that archives logs older than 30 days
  4. Write a script that generates a directory tree with sizes (like tree command)
  5. Create a file watcher that alerts when files are added to a specific folder

Next: Working with CSV, JSON, and XML — learn data processing!