How to Delete Files Only from a Directory in PowerShell Without Removing Subdirectories


2 views

When working with PowerShell's Remove-Item cmdlet, many developers encounter unexpected behavior when trying to clean up directories. The initial approach of using either:

Remove-Item "D:\MyTemp"
Remove-Item "D:\MyTemp\*"

fails to achieve the desired result because:

  • The first command would attempt to delete the directory itself
  • The second command might leave files behind due to hidden/system attributes

To exclusively delete files while preserving the directory structure, use this approach:

Get-ChildItem -Path "D:\MyTemp" -File | Remove-Item -Force

This command:

  • Targets only files (-File parameter)
  • Pipes them to Remove-Item
  • Includes hidden/system files (-Force)

Here are some practical variations for different scenarios:

# Delete specific file types only
Get-ChildItem -Path "D:\MyTemp\*.tmp" -File | Remove-Item

# Recursive deletion (files in all subdirectories)
Get-ChildItem -Path "D:\MyTemp" -File -Recurse | Remove-Item -Force

# Delete files older than 30 days
$cutoffDate = (Get-Date).AddDays(-30)
Get-ChildItem -Path "D:\MyTemp" -File | Where-Object {$_.LastWriteTime -lt $cutoffDate} | Remove-Item

The wildcard pattern in Remove-Item "D:\MyTemp\*" has limitations:

  • It won't remove hidden/system files by default
  • It processes items sequentially which can cause issues with large directories
  • The behavior differs slightly between PowerShell versions

For robust file deletion in enterprise environments:

try {
    $files = Get-ChildItem -Path "D:\MyTemp" -File -ErrorAction Stop
    $files | Remove-Item -Force -ErrorAction Stop
    Write-Host "Successfully deleted $($files.Count) files"
}
catch {
    Write-Error "Deletion failed: $_"
}

Key improvements:

  • Proper error handling
  • Progress feedback
  • Explicit error action preferences

When you run Remove-Item "D:\MyTemp\*", PowerShell doesn't actually delete the files as you'd expect. The command appears to execute without errors, but checking the directory reveals all files remain intact. This behavior confuses many PowerShell beginners.

The primary reason your files aren't being deleted lies in how PowerShell handles wildcard patterns and confirmation prompts. By default, PowerShell asks for confirmation when deleting files using wildcards, but the prompt might not be visible depending on your execution context.

Here are three reliable methods to delete only files while preserving directories:

# Method 1: Force deletion without confirmation
Get-ChildItem -Path "D:\MyTemp" -File | Remove-Item -Force

# Method 2: Explicitly target files only
Remove-Item -Path "D:\MyTemp\*.*" -Include * -Exclude *.*.*

# Method 3: Using recurse parameter carefully
Remove-Item -Path "D:\MyTemp\*" -Recurse -Include * -Exclude *.*.* -WhatIf

For more complex file deletion needs, consider these patterns:

# Delete files older than 30 days
Get-ChildItem -Path "D:\MyTemp" -File |
Where-Object { $_.LastWriteTime -lt (Get-Date).AddDays(-30) } |
Remove-Item -Force

# Delete specific file types only
Get-ChildItem -Path "D:\MyTemp\*.tmp" -File | Remove-Item

# Delete empty files
Get-ChildItem -Path "D:\MyTemp" -File |
Where-Object { $_.length -eq 0 } |
Remove-Item -Verbose
  • Always test with -WhatIf parameter first
  • Consider adding -Verbose for better logging
  • For scheduled tasks, use absolute paths
  • Combine with Try/Catch blocks for error handling
# Example with error handling
try {
    Get-ChildItem -Path "D:\MyTemp" -File -ErrorAction Stop |
    Remove-Item -Force -ErrorAction Stop
}
catch {
    Write-Warning "Error occurred: $_"
}