如何使用PowerShell将文件移动到回收站?

56

在PowerShell中使用rm命令删除文件时,它们将被永久删除。

与此不同的是,我希望已删除的项目能够进入回收站,就像通过 UI 删除文件时发生的情况一样。

您如何在PowerShell中实现这一点?


3
选定以下解决方案后,您可以通过Set-Alias rm Remove-ItemSafely -Option AllScope更新rm别名以使用它。 - bdukes
8个回答

42

2017年的答案:使用 Recycle 模块


Install-Module -Name Recycle

然后运行:

Remove-ItemSafely file

我喜欢给这个起一个别名叫做trash


1
@KahnKah 使用 .\* 代替 file,但这也会删除所有子目录。 - Monday Fatigue
@Neonit 是的,这也适用于所有第三方软件。 - mikemaccana
@mikemaccana 是的,但这个命令看起来非常像没有第三方参与,而是来自微软,因为没有给出任何URL或其他提示表明它来自公共存储库。 - Neonit
需要注意的是,本模块的作者是Brian Dukes,版权所有(c)2016 Engage Software。这不是官方的Microsoft模块。 - undefined
@Chiramisu 这是真的,但我认为大多数软件开发人员都明白从在线软件包提供商(如PS Gallery、npm、PyPI等)下载的模块来自第三方,而不是来自微软、Node基金会、Python软件基金会等。 - undefined
显示剩余6条评论

34

如果你不想总是看到确认提示,可以使用以下方法:

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

(感谢 Shay Levy 提供的解决方案)


5
避免提示加1!顺便提醒一下,还有DeleteDirectory的存在。 - marsze

21

在PowerShell中,它的工作方式与Chris Ballance在JScript中的解决方案基本相同:

 $shell = new-object -comobject "Shell.Application"
 $folder = $shell.Namespace("<path to file>")
 $item = $folder.ParseName("<name of file>")
 $item.InvokeVerb("delete")

你的答案有一个小错误(但它确实起作用了!)。在“path to file”之前需要加上引号:$folder = $shell.Namespace("<path to file>") - Omar Shahine
1
路径中只需要引号,如果有空格。 - RayofCommand

19

以下是一个缩短了一些工作量的较短版本

$path = "<path to file>"
$shell = new-object -comobject "Shell.Application"
$item = $shell.Namespace(0).ParseName("$path")
$item.InvokeVerb("delete")

2
这会弹出一个确认窗口。 - Кое Кто

10

这里是一个改进后的函数,支持将目录和文件作为输入:

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')
        }
    }
}

4

将文件移动到回收站:

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

将文件夹移到回收站:

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

1
这是对sba923s的优秀回答进行的轻微修改。
我改变了一些东西,比如参数传递,并添加了一个-WhatIf来测试文件或目录的删除。
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


0

这里有一个完整的解决方案,可以添加到您的用户配置文件中,使得“rm”命令将文件发送到回收站。在我的有限测试中,它比以前的解决方案更好地处理相对路径。

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接