PowerShell File System Management

PowerShell provides a complete set of cmdlets for managing files, folders, and drives. Tasks that previously required File Explorer menus or third-party tools — creating folder structures, bulk renaming, copying thousands of files, cleaning up old logs — all become single commands or short scripts with PowerShell.

PowerShell Providers and Drives

PowerShell accesses the file system through a provider. The FileSystem provider maps drives like C:, D:, and network paths into a navigable tree. PowerShell also has other providers for the Registry, certificates, and environment variables — all navigated with the same cmdlets.


# List all available providers
Get-PSProvider

# List all available drives
Get-PSDrive

Navigating the File System


# Show current location
Get-Location
# Alias: pwd

# Change directory
Set-Location -Path "C:\Users\Admin\Documents"
# Alias: cd

# Go up one level
Set-Location ..

# Go to home directory
Set-Location ~

# Go to previous location
Set-Location -

Listing Files and Folders


# List contents of current folder
Get-ChildItem
# Aliases: ls, dir

# List a specific folder
Get-ChildItem -Path "C:\Windows"

# List with details (size, date)
Get-ChildItem -Path "C:\Data" | Format-Table Name, Length, LastWriteTime -AutoSize

# List only files (no folders)
Get-ChildItem -Path "C:\Data" -File

# List only folders
Get-ChildItem -Path "C:\Data" -Directory

# Filter by extension
Get-ChildItem -Path "C:\Data" -Filter "*.csv"

# Recursive listing (all subfolders)
Get-ChildItem -Path "C:\Projects" -Recurse

# Recursive with filter
Get-ChildItem -Path "C:\Logs" -Filter "*.log" -Recurse

Creating Files and Folders


# Create a folder
New-Item -Path "C:\Reports\2026" -ItemType Directory

# Create a file
New-Item -Path "C:\Reports\2026\summary.txt" -ItemType File

# Create a file with content
New-Item -Path "C:\Config\settings.ini" -ItemType File -Value "env=production"

# Create nested folder structure (all at once)
New-Item -Path "C:\Projects\App\src\utils" -ItemType Directory -Force

Copying Files and Folders


# Copy a single file
Copy-Item -Path "C:\Reports\report.xlsx" -Destination "D:\Backup\report.xlsx"

# Copy a file with a new name
Copy-Item -Path "C:\Data\config.xml" -Destination "C:\Data\config_backup.xml"

# Copy an entire folder (recursive)
Copy-Item -Path "C:\Projects\App" -Destination "D:\Backup\App" -Recurse

# Copy multiple files matching a pattern
Copy-Item -Path "C:\Logs\*.log" -Destination "D:\LogBackup\"

# Overwrite if destination exists
Copy-Item -Path "C:\Data\file.txt" -Destination "D:\Backup\file.txt" -Force

Moving Files and Folders


# Move a file
Move-Item -Path "C:\Temp\report.pdf" -Destination "C:\Reports\report.pdf"

# Move and rename at the same time
Move-Item -Path "C:\Temp\data.csv" -Destination "C:\Archive\data_2026.csv"

# Move a folder
Move-Item -Path "C:\Projects\OldApp" -Destination "D:\Archive\OldApp"

Renaming Files and Folders


# Rename a file
Rename-Item -Path "C:\Reports\old_name.txt" -NewName "new_name.txt"

# Rename a folder
Rename-Item -Path "C:\Projects\v1" -NewName "v2"

# Bulk rename – add a prefix to all .txt files
Get-ChildItem -Path "C:\Reports" -Filter "*.txt" | ForEach-Object {
    Rename-Item -Path $_.FullName -NewName "2026_$($_.Name)"
}

Deleting Files and Folders


# Delete a file
Remove-Item -Path "C:\Temp\junk.txt"

# Delete without confirmation prompt
Remove-Item -Path "C:\Temp\junk.txt" -Force

# Delete a folder and all its contents
Remove-Item -Path "C:\Temp\OldProject" -Recurse -Force

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

Reading and Writing File Content


# Read a text file (returns array of lines)
$lines = Get-Content -Path "C:\Config\settings.txt"

# Read as one string
$text = Get-Content -Path "C:\Config\settings.txt" -Raw

# Read only first 5 lines
Get-Content -Path "C:\Logs\app.log" -TotalCount 5

# Read last 10 lines (like tail)
Get-Content -Path "C:\Logs\app.log" -Tail 10

# Write (overwrite) content to file
Set-Content -Path "C:\Config\settings.txt" -Value "mode=production"

# Append content to file
Add-Content -Path "C:\Logs\audit.log" -Value "$(Get-Date) - Script run complete"

Testing Path Existence


# Check if path exists
Test-Path -Path "C:\Reports"          # True or False

# Check if it is a file
Test-Path -Path "C:\Reports\data.csv" -PathType Leaf

# Check if it is a folder
Test-Path -Path "C:\Reports" -PathType Container

# Create folder only if it does not exist
if (-not (Test-Path "C:\Reports\2026")) {
    New-Item -Path "C:\Reports\2026" -ItemType Directory
    Write-Host "Folder created."
} else {
    Write-Host "Folder already exists."
}

File and Folder Properties


$file = Get-Item -Path "C:\Reports\monthly.xlsx"

Write-Host "Name:          $($file.Name)"
Write-Host "Full Path:     $($file.FullName)"
Write-Host "Size (KB):     $([math]::Round($file.Length / 1KB, 2))"
Write-Host "Created:       $($file.CreationTime)"
Write-Host "Last Modified: $($file.LastWriteTime)"
Write-Host "Extension:     $($file.Extension)"
Write-Host "Is ReadOnly:   $($file.IsReadOnly)"

Disk Space Information


# Get disk space for all drives
Get-PSDrive -PSProvider FileSystem | Select-Object Name,
    @{Name="UsedGB";  Expression={[math]::Round($_.Used/1GB, 2)}},
    @{Name="FreeGB";  Expression={[math]::Round($_.Free/1GB, 2)}},
    @{Name="TotalGB"; Expression={[math]::Round(($_.Used + $_.Free)/1GB, 2)}}

Output:


Name  UsedGB  FreeGB  TotalGB
----  ------  ------  -------
C     145.32   74.68   220.00
D      55.10  144.90   200.00

Working with File Paths


$path = "C:\Projects\App\src\main.ps1"

# Split path components
Split-Path $path -Parent      # C:\Projects\App\src
Split-Path $path -Leaf        # main.ps1
Split-Path $path -Extension   # .ps1 (PowerShell 7+)

# Combine paths safely
Join-Path -Path "C:\Reports" -ChildPath "2026\summary.xlsx"
# Output: C:\Reports\2026\summary.xlsx

# Resolve to absolute path
Resolve-Path ".\scripts"

Real-World Example – Automated Archive Script


function Archive-OldLogs {
    param (
        [string]$LogFolder   = "C:\Logs",
        [string]$ArchiveRoot = "D:\LogArchive",
        [int]$DaysOld        = 30
    )

    $cutoff     = (Get-Date).AddDays(-$DaysOld)
    $monthFolder = Get-Date -Format "yyyy-MM"
    $archivePath = Join-Path $ArchiveRoot $monthFolder

    # Create archive folder if needed
    if (-not (Test-Path $archivePath)) {
        New-Item -Path $archivePath -ItemType Directory | Out-Null
        Write-Host "Archive folder created: $archivePath"
    }

    # Find and move old log files
    $oldFiles = Get-ChildItem -Path $LogFolder -Filter "*.log" |
                Where-Object { $_.LastWriteTime -lt $cutoff }

    if ($oldFiles.Count -eq 0) {
        Write-Host "No old log files to archive."
        return
    }

    foreach ($file in $oldFiles) {
        $dest = Join-Path $archivePath $file.Name
        Move-Item -Path $file.FullName -Destination $dest
        Write-Host "Archived: $($file.Name)"
    }

    Write-Host "Done. $($oldFiles.Count) file(s) archived to $archivePath"
}

Archive-OldLogs

Summary

PowerShell's file system cmdlets cover every daily file management task. New-Item creates files and folders. Copy-Item and Move-Item handle duplicating and relocating content. Rename-Item renames in bulk with a loop. Remove-Item deletes with recursive and force options. Get-Content, Set-Content, and Add-Content handle reading and writing text. Test-Path prevents errors from operating on missing paths. Combined with Get-ChildItem filters and Where-Object date conditions, these tools automate complex file management workflows that would otherwise require manual effort.

Leave a Comment