56

When using the rm command to delete files in Powershell, they are permanently deleted.

Instead of this, I would like to have the deleted item go to the recycle bin, like what happens when files are deleted through the UI.

How can you do this in PowerShell?

KetZoomer
  • 2,701
  • 3
  • 15
  • 43
Omar Shahine
  • 1,935
  • 3
  • 22
  • 30
  • 3
    Once you've picked a solution below, you can update the `rm` alias to use it via `Set-Alias rm Remove-ItemSafely -Option AllScope` – bdukes Jul 31 '15 at 15:46

8 Answers8

40

2017 answer: use the Recycle module

Install-Module -Name Recycle

Then run:

Remove-ItemSafely file

I like to make an alias called trash for this.

mikemaccana
  • 110,530
  • 99
  • 389
  • 494
34

If you don't want to always see the confirmation prompt, use the following:

Add-Type -AssemblyName Microsoft.VisualBasic
[Microsoft.VisualBasic.FileIO.FileSystem]::DeleteFile('d:\foo.txt','OnlyErrorDialogs','SendToRecycleBin')

(solution courtesy of Shay Levy)

John Pankowicz
  • 4,203
  • 2
  • 29
  • 47
21

It works in PowerShell pretty much the same way as Chris Ballance's solution in JScript:

 $shell = new-object -comobject "Shell.Application"
 $folder = $shell.Namespace("<path to file>")
 $item = $folder.ParseName("<name of file>")
 $item.InvokeVerb("delete")
Scott Saad
  • 17,962
  • 11
  • 63
  • 84
Alex Shirshov
  • 635
  • 3
  • 8
19

Here is a shorter version that reduces a bit of work

$path = "<path to file>"
$shell = new-object -comobject "Shell.Application"
$item = $shell.Namespace(0).ParseName("$path")
$item.InvokeVerb("delete")
Omar Shahine
  • 1,935
  • 3
  • 22
  • 30
10

Here's an improved function that supports directories as well as files as input:

Add-Type -AssemblyName Microsoft.VisualBasic

function Remove-Item-ToRecycleBin($Path) {
    $item = Get-Item -Path $Path -ErrorAction SilentlyContinue
    if ($item -eq $null)
    {
        Write-Error("'{0}' not found" -f $Path)
    }
    else
    {
        $fullpath=$item.FullName
        Write-Verbose ("Moving '{0}' to the Recycle Bin" -f $fullpath)
        if (Test-Path -Path $fullpath -PathType Container)
        {
            [Microsoft.VisualBasic.FileIO.FileSystem]::DeleteDirectory($fullpath,'OnlyErrorDialogs','SendToRecycleBin')
        }
        else
        {
            [Microsoft.VisualBasic.FileIO.FileSystem]::DeleteFile($fullpath,'OnlyErrorDialogs','SendToRecycleBin')
        }
    }
}
sba923
  • 537
  • 1
  • 5
  • 9
3

Remove file to RecycleBin:

Add-Type -AssemblyName Microsoft.VisualBasic
[Microsoft.VisualBasic.FileIO.FileSystem]::DeleteFile('e:\test\test.txt','OnlyErrorDialogs','SendToRecycleBin')

Remove folder to RecycleBin:

Add-Type -AssemblyName Microsoft.VisualBasic
[Microsoft.VisualBasic.FileIO.FileSystem]::Deletedirectory('e:\test\testfolder','OnlyErrorDialogs','SendToRecycleBin')
Mario Cianciolo
  • 1,223
  • 10
  • 17
1

Here's slight mod to sba923s' great answer.

I've changed a few things like the parameter passing and added a -WhatIf to test the deletion for the file or directory.

function Remove-ItemToRecycleBin {

  Param
  (
    [Parameter(Mandatory = $true, HelpMessage = 'Directory path of file path for deletion.')]
    [String]$LiteralPath,
    [Parameter(Mandatory = $false, HelpMessage = 'Switch for allowing the user to test the deletion first.')]
    [Switch]$WhatIf
    )

  Add-Type -AssemblyName Microsoft.VisualBasic
  $item = Get-Item -LiteralPath $LiteralPath -ErrorAction SilentlyContinue

  if ($item -eq $null) {
    Write-Error("'{0}' not found" -f $LiteralPath)
  }
  else {
    $fullpath = $item.FullName

    if (Test-Path -LiteralPath $fullpath -PathType Container) {
      if (!$WhatIf) {
        Write-Verbose ("Moving '{0}' folder to the Recycle Bin" -f $fullpath)
        [Microsoft.VisualBasic.FileIO.FileSystem]::DeleteDirectory($fullpath,'OnlyErrorDialogs','SendToRecycleBin')
      }
      else {
        Write-Host "Testing deletion of folder: $fullpath"
      }
    }
    else {
      if (!$WhatIf) {
        Write-Verbose ("Moving '{0}' file to the Recycle Bin" -f $fullpath)
        [Microsoft.VisualBasic.FileIO.FileSystem]::DeleteFile($fullpath,'OnlyErrorDialogs','SendToRecycleBin')
      }
      else {
        Write-Host "Testing deletion of file: $fullpath"
      }
    }
  }

}

$tempFile = [Environment]::GetFolderPath("Desktop") + "\deletion test.txt"
"stuff" | Out-File -FilePath $tempFile

$fileToDelete = $tempFile

Start-Sleep -Seconds 2 # Just here for you to see the file getting created before deletion.

# Tests the deletion of the folder or directory.
Remove-ItemToRecycleBin -WhatIf -LiteralPath $fileToDelete
# PS> Testing deletion of file: C:\Users\username\Desktop\deletion test.txt

# Actually deletes the file or directory.
# Remove-ItemToRecycleBin -LiteralPath $fileToDelete

Ste
  • 1,729
  • 1
  • 17
  • 27
0

Here is a complete solution that can be added to your user profile to make 'rm' send files to the Recycle Bin. In my limited testing, it handles relative paths better than the previous solutions.

Add-Type -AssemblyName Microsoft.VisualBasic

function Remove-Item-toRecycle($item) {
    Get-Item -Path $item | %{ $fullpath = $_.FullName}
    [Microsoft.VisualBasic.FileIO.FileSystem]::DeleteFile($fullpath,'OnlyErrorDialogs','SendToRecycleBin')
}

Set-Alias rm Remove-Item-toRecycle -Option AllScope
Mark S.
  • 1
  • 1