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
Navigating the File System
# 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 10Writing 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-DownloadsExercises
- Write a script that backs up all
.ps1files from a folder to a dated backup folder - Create a function that finds and removes all empty folders recursively
- Build a log rotation script that archives logs older than 30 days
- Write a script that generates a directory tree with sizes (like
treecommand) - Create a file watcher that alerts when files are added to a specific folder
Next: Working with CSV, JSON, and XML — learn data processing!