By Davy Rogers. Use these techniques only in environments you own or have explicit permission to test.

PowerShell: File Operations

File operations are fundamental to any scripting language. PowerShell provides powerful cmdlets for creating, reading, copying, moving, and deleting files and directories. This lesson covers everything you need to manage the file system effectively in Windows environments.

What You'll Learn

  • Creating files and directories
  • Reading and writing file content
  • Copying and moving files
  • Deleting files and directories
  • Testing file existence
  • Working with file properties
  • Recursive operations
  • Practical pentesting scenarios

Creating Files and Directories

Create New File

# Empty file
New-Item file.txt -ItemType File

# With content
New-Item file.txt -ItemType File -Value "Hello, World!"

# Force overwrite if exists
New-Item file.txt -ItemType File -Force

# Multiple files
New-Item file1.txt, file2.txt, file3.txt -ItemType File

Create New Directory

# Single directory
New-Item MyFolder -ItemType Directory

# Nested directories
New-Item C:\Parent\Child\GrandChild -ItemType Directory -Force

# Multiple directories
New-Item Folder1, Folder2, Folder3 -ItemType Directory

Reading File Content

Get-Content

# Read entire file
Get-Content file.txt

# Alias
cat file.txt
type file.txt
gc file.txt

# Read first 10 lines
Get-Content file.txt -Head 10

# Read last 10 lines
Get-Content file.txt -Tail 10

# Read specific line range (first get all, then select)
Get-Content file.txt | Select-Object -First 20 | Select-Object -Last 10

# Real-time monitoring (like tail -f)
Get-Content file.txt -Wait -Tail 10

Reading Binary Files

# Read as bytes
Get-Content file.exe -Encoding Byte

# Read with specific encoding
Get-Content file.txt -Encoding UTF8
Get-Content file.txt -Encoding ASCII

Writing File Content

Set-Content (Overwrite)

# Write to file (overwrites)
Set-Content file.txt "New content"

# Write multiple lines
Set-Content file.txt "Line 1", "Line 2", "Line 3"

# From pipeline
"Hello" | Set-Content file.txt

Add-Content (Append)

# Append to file
Add-Content file.txt "New line"

# Append multiple lines
Add-Content file.txt "Line 4", "Line 5"

# From pipeline
"Another line" | Add-Content file.txt

Out-File

# Write to file
"Hello, World!" | Out-File file.txt

# Append mode
"New line" | Out-File file.txt -Append

# Specify encoding
"Content" | Out-File file.txt -Encoding UTF8

# No newline
"Text" | Out-File file.txt -NoNewline

Copying Files

Copy-Item

# Copy file
Copy-Item source.txt destination.txt

# Copy to directory
Copy-Item file.txt C:\Destination\

# Copy multiple files
Copy-Item *.txt C:\Backup\

# Copy with wildcard
Copy-Item C:\Source\*.log C:\Logs\

# Copy directory (recursive)
Copy-Item C:\Source C:\Destination -Recurse

# Copy with force (overwrite)
Copy-Item file.txt C:\Destination\ -Force

# Copy and rename
Copy-Item oldname.txt newname.txt

Moving Files

Move-Item

# Move file
Move-Item source.txt C:\Destination\

# Rename file (move to same directory with new name)
Move-Item oldname.txt newname.txt

# Move multiple files
Move-Item *.log C:\Logs\

# Move directory
Move-Item C:\OldFolder C:\NewLocation\

# Force overwrite
Move-Item file.txt C:\Destination\ -Force

Deleting Files

Remove-Item

# Delete file
Remove-Item file.txt

# Delete multiple files
Remove-Item *.tmp

# Delete directory (must be empty)
Remove-Item EmptyFolder

# Delete directory and contents (recursive)
Remove-Item MyFolder -Recurse

# Force delete (no confirmation)
Remove-Item file.txt -Force

# Delete with confirmation
Remove-Item important.txt -Confirm

# Delete but exclude certain files
Get-ChildItem *.txt | Where-Object {$_.Name -ne "keep.txt"} | Remove-Item

Testing File Existence

Test-Path

# Check if file exists
Test-Path file.txt

# Check if directory exists
Test-Path C:\Folder

# Use in conditional
if (Test-Path file.txt) {
    Write-Host "File exists!"
} else {
    Write-Host "File not found"
}

# Check path type
Test-Path file.txt -PathType Leaf     # File
Test-Path C:\Folder -PathType Container  # Directory

Listing Files and Directories

Get-ChildItem

# List current directory
Get-ChildItem

# Aliases
ls
dir
gci

# List specific directory
Get-ChildItem C:\Windows

# Include hidden files
Get-ChildItem -Force

# Recursive (all subdirectories)
Get-ChildItem -Recurse

# Filter by extension
Get-ChildItem *.txt

# Filter by name pattern
Get-ChildItem *log*

# Files only
Get-ChildItem -File

# Directories only
Get-ChildItem -Directory

# Depth limit (how many levels deep)
Get-ChildItem -Recurse -Depth 2

File Properties

Get File Information

# Get file object
$file = Get-Item file.txt

# Properties
$file.Name              # Filename
$file.FullName          # Full path
$file.Length            # Size in bytes
$file.Extension         # File extension
$file.CreationTime      # Created date/time
$file.LastWriteTime     # Modified date/time
$file.LastAccessTime    # Last accessed
$file.Attributes        # File attributes

# Display all properties
$file | Get-Member -MemberType Property

Set File Properties

# Change file attributes
(Get-Item file.txt).Attributes = "ReadOnly"
(Get-Item file.txt).Attributes = "Hidden"
(Get-Item file.txt).Attributes = "Archive"

# Remove attribute
$file = Get-Item file.txt
$file.Attributes = $file.Attributes -band (-bnot [System.IO.FileAttributes]::ReadOnly)

# Change timestamps
(Get-Item file.txt).LastWriteTime = Get-Date

Working with Paths

Path Manipulation

# Get file name from path
Split-Path C:\Folder\file.txt -Leaf
# Output: file.txt

# Get directory from path
Split-Path C:\Folder\file.txt -Parent
# Output: C:\Folder

# Get file extension
[System.IO.Path]::GetExtension("file.txt")
# Output: .txt

# Get file name without extension
[System.IO.Path]::GetFileNameWithoutExtension("file.txt")
# Output: file

# Combine paths
Join-Path C:\Folder file.txt
# Output: C:\Folder\file.txt

# Resolve relative path
Resolve-Path .\file.txt

# Convert to absolute path
(Get-Item file.txt).FullName

Filtering and Sorting

Where-Object

# Files larger than 1MB
Get-ChildItem | Where-Object {$_.Length -gt 1MB}

# Files modified in last 7 days
Get-ChildItem | Where-Object {$_.LastWriteTime -gt (Get-Date).AddDays(-7)}

# Files with specific extension
Get-ChildItem | Where-Object {$_.Extension -eq ".txt"}

# Files older than 30 days
Get-ChildItem | Where-Object {$_.LastWriteTime -lt (Get-Date).AddDays(-30)}

Sort-Object

# Sort by name
Get-ChildItem | Sort-Object Name

# Sort by size (largest first)
Get-ChildItem | Sort-Object Length -Descending

# Sort by date modified
Get-ChildItem | Sort-Object LastWriteTime -Descending

# Multiple sort criteria
Get-ChildItem | Sort-Object Extension, Name

Practical Examples

Example 1: Find Large Files

# Files larger than 100MB
Get-ChildItem -Recurse -File | 
    Where-Object {$_.Length -gt 100MB} | 
    Sort-Object Length -Descending | 
    Select-Object FullName, @{Name="Size(MB)";Expression={[math]::Round($_.Length/1MB, 2)}}

Example 2: Clean Old Log Files

# Delete .log files older than 30 days
Get-ChildItem -Path C:\Logs -Filter *.log | 
    Where-Object {$_.LastWriteTime -lt (Get-Date).AddDays(-30)} | 
    Remove-Item -Verbose

Example 3: Backup Files

# Backup all .txt files with timestamp
$timestamp = Get-Date -Format "yyyyMMdd_HHmmss"
$backupDir = "C:\Backup\$timestamp"
New-Item $backupDir -ItemType Directory -Force
Get-ChildItem *.txt | Copy-Item -Destination $backupDir

Example 4: Count Files by Extension

# Count files by extension
Get-ChildItem -Recurse -File | 
    Group-Object Extension | 
    Select-Object Name, Count | 
    Sort-Object Count -Descending

Example 5: Find Duplicate Files

# Find files with same name
Get-ChildItem -Recurse | 
    Group-Object Name | 
    Where-Object {$_.Count -gt 1} | 
    Select-Object Name, Count

Practical Pentesting Scenarios

Scenario 1: Search for Credentials

# Search for "password" in .txt and .config files
Get-ChildItem -Recurse -Include *.txt, *.config | 
    Select-String "password" -CaseSensitive:$false

Scenario 2: Find Writeable Directories

# Find directories where current user can write
Get-ChildItem C:\ -Directory -Recurse -ErrorAction SilentlyContinue | 
    Where-Object {
        try {
            [System.IO.File]::OpenWrite($_.FullName).Close()
            $true
        } catch {
            $false
        }
    }

Scenario 3: Collect System Information

# Export system info to file
$output = "system_info_$(Get-Date -Format 'yyyyMMdd').txt"

"=== System Information ===" | Out-File $output
Get-ComputerInfo | Out-File $output -Append

"=== Installed Software ===" | Out-File $output -Append
Get-WmiObject -Class Win32_Product | Select-Object Name, Version | Out-File $output -Append

Scenario 4: Find Sensitive Files

# Find files with sensitive keywords in name
$keywords = @("password", "credential", "secret", "key", "token")
foreach ($keyword in $keywords) {
    Get-ChildItem -Recurse -Filter "*$keyword*" -ErrorAction SilentlyContinue
}

Scenario 5: Exfiltrate Files

# Copy interesting files to staging area
$staging = "C:\Temp\loot"
New-Item $staging -ItemType Directory -Force

# Copy configs
Get-ChildItem -Recurse -Include *.config, *.ini | 
    Copy-Item -Destination $staging -Force

# Copy database files
Get-ChildItem -Recurse -Include *.db, *.sqlite | 
    Copy-Item -Destination $staging -Force

Working with CSV/JSON

CSV Operations

# Export to CSV
Get-Process | Export-Csv processes.csv -NoTypeInformation

# Import from CSV
$data = Import-Csv processes.csv

# Filter imported data
Import-Csv data.csv | Where-Object {$_.Age -gt 25}

JSON Operations

# Export to JSON
Get-Process | Select-Object Name, Id, CPU | ConvertTo-Json | Out-File processes.json

# Import from JSON
$data = Get-Content data.json | ConvertFrom-Json

# Access properties
$data.Name
$data.Id

Error Handling

Try-Catch

try {
    Remove-Item C:\ImportantFile.txt -ErrorAction Stop
    Write-Host "File deleted successfully"
} catch {
    Write-Host "Error: $_"
}

Error Action

# Stop on error
Get-Content nonexistent.txt -ErrorAction Stop

# Continue silently
Get-ChildItem C:\Windows -Recurse -ErrorAction SilentlyContinue

# Store errors in variable
Get-ChildItem C:\ -Recurse -ErrorVariable myErrors -ErrorAction SilentlyContinue

Quick Reference

Create:
New-Item file.txt -ItemType File
New-Item Folder -ItemType Directory

Read:
Get-Content file.txt
Get-Content file.txt -Head 10
Get-Content file.txt -Tail 10

Write:
Set-Content file.txt "content"      # Overwrite
Add-Content file.txt "new line"     # Append
"text" | Out-File file.txt

Copy/Move:
Copy-Item source.txt dest.txt
Move-Item source.txt dest.txt
Copy-Item Folder Dest -Recurse

Delete:
Remove-Item file.txt
Remove-Item Folder -Recurse

List:
Get-ChildItem
Get-ChildItem -Recurse
Get-ChildItem *.txt

Test:
Test-Path file.txt
Test-Path C:\Folder

Filter:
Get-ChildItem | Where-Object {$_.Length -gt 1MB}
Get-ChildItem | Sort-Object Length -Descending

Resources

Help Commands

Get-Help New-Item -Examples
Get-Help Get-Content -Full
Get-Help Copy-Item -Online

Online


Next Steps

  1. Practice daily - manage files with PowerShell instead of Explorer
  2. Combine cmdlets with pipelines
  3. Learn regex for advanced pattern matching
  4. Explore recursion for deep file operations
  5. Automate backups and maintenance tasks

File operations are the foundation of PowerShell automation. Master these and you'll be incredibly productive!


"Get-ChildItem: Because 'dir' is so DOS."