Skip to content

Instantly share code, notes, and snippets.

@lazywinadmin
Created April 20, 2015 14:37
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save lazywinadmin/f630c2fda0d52bfb6452 to your computer and use it in GitHub Desktop.
Save lazywinadmin/f630c2fda0d52bfb6452 to your computer and use it in GitHub Desktop.
RecycleBin PowerShell script
<#
This script creates object which correctly works with ntfs streams and reparse points
Usage samples:
'.\*.bak' | recycle -WipeOut -> multiplies objects by zero
recycle -Path '.\*.ini' -> sends objects to Recycle Bin
$RecycleBin.Measure() -> returns true size of all items in Recycle Bin
$RecycleBin.Clear() -> this is obvious
$RecycleBin.List() -> returns friendly items list
More examples:
$RecycleBin.Measure('*.mkv')
$RecycleBin.Clear('*.txt')
$RecycleBin.List('*.doc')
$RecycleBin.List('film.mkv').Measure()
$RecycleBin.List('good.exe').Restore()
$RecycleBin.List('virus.exe').Delete()
$time_to_die = [TimeSpan]::FromDays(20)
($RecycleBin.List() | where PermanentState -GE $time_to_die).Delete()
#>
$shell32_wrapper = @"
using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
namespace shell32 {
// Put all the variables required for the DLLImports here
enum RecycleFlags : uint { SHERB_NOCONFIRMATION = 0x00000001, SHERB_NOPROGRESSUI = 0x00000002, SHERB_NOSOUND = 0x00000004 }
public static class RecycleBin {
[DllImport("Shell32.dll",CharSet=CharSet.Unicode)]
internal static extern uint SHEmptyRecycleBin(IntPtr hwnd, string pszRootPath, RecycleFlags dwFlags);
[DllImport("Shell32.dll",CharSet=CharSet.Unicode)]
internal static extern uint SHUpdateRecycleBinIcon();
}
public class ShellWrapper : IDisposable {
// Creates a new wrapper for the local machine
public ShellWrapper() { }
// Disposes of this wrapper
public void Dispose() {
GC.SuppressFinalize(this);
}
// Put public functions here
public void Empty() {
RecycleBin.SHEmptyRecycleBin(IntPtr.Zero, null, RecycleFlags.SHERB_NOCONFIRMATION | RecycleFlags.SHERB_NOPROGRESSUI | RecycleFlags.SHERB_NOSOUND);
}
public void IconUpdate() {
RecycleBin.SHUpdateRecycleBinIcon();
}
// Occurs on destruction of the Wrapper
~ShellWrapper() {
Dispose();
}
} // Wrapper class
}
"@
Add-type -AssemblyName "Microsoft.VisualBasic"
Add-Type -TypeDefinition $shell32_wrapper
## =================
Function Recycle-Item
{
[CmdletBinding()]
Param(
[Parameter(Position=0,Mandatory,ValueFromPipeline)][System.Object[]]$Path,
[Parameter(Position=1,Mandatory=$false)][switch]$WipeOut
)
Begin
{
$dialog_mode = [Microsoft.VisualBasic.FileIO.UIOption]::OnlyErrorDialogs
$recycle_mode_default = [Microsoft.VisualBasic.FileIO.RecycleOption]::SendToRecycleBin
$recycle_mode_wipeout = [Microsoft.VisualBasic.FileIO.RecycleOption]::DeletePermanently
$recycle_mode = switch -Exact ($WipeOut) {$true{$recycle_mode_wipeout};Default{$recycle_mode_default}}
}
Process
{
$Path | gi -Force -ErrorAction 'SilentlyContinue' | foreach -Process {
if ($_.Mode[0] -eq [char]0x64)
{
"Removing directory: `"$($_.FullName)`"" | Write-Verbose
[Microsoft.VisualBasic.FileIO.FileSystem]::DeleteDirectory($_.FullName,$dialog_mode,$recycle_mode)
}
else
{
"Removing file: `"$($_.FullName)`"" | Write-Verbose
[Microsoft.VisualBasic.FileIO.FileSystem]::DeleteFile($_.FullName,$dialog_mode,$recycle_mode)
}
}
}
}
Set-Alias -Name 'recycle' -Value Recycle-Item
## =================
$method = @{}
$method['List'] = {
.{ param ([Parameter(Mandatory=$false)][string]$Mask)} @args
$actual_list = $this.Items() | select
if ($Mask) { $actual_list = $actual_list | where -Property 'Name' -like -Value $Mask }
$sked = @()
$actual_list | foreach {
$rec = $_ | select 'Name','Type',
@{Name = 'PermanentState'; Expression = { [DateTime]::Now - $_.ModifyDate }},
@{Name = 'Object'; Expression = { gi -LiteralPath $_.Path -Force }},
@{Name = 'Actions'; Expression = { $_.Verbs() | select }}
$rec | Add-Member -MemberType 'ScriptMethod' -Name 'RemoveInfoFile' -Value {
$t = $this.Object
"$($t.PSParentPath)\$($t.PSChildName.Replace('$R','$I'))" | ri
}
$rec | Add-Member -MemberType 'ScriptMethod' -Name 'Delete' -Value {
$this.Object | recycle -WipeOut
$this.RemoveInfoFile()
}
$rec | Add-Member -MemberType 'ScriptMethod' -Name 'Restore' -Value {
$this.Actions[0].DoIt()
if (!$this.Object.Exists) { $this.RemoveInfoFile() }
}
$rec | Add-Member -MemberType 'ScriptMethod' -Name 'Measure' -Value {
Set-Variable -Name _measure -Value @{
Item = $this.Name
Links = 0
Files = 0
Folders = 0
Size = 0
} -Option AllScope
function calculate ([System.Object]$Obj, [System.IO.DirectoryInfo]$Fol)
{
if (-not $Obj) { $Obj = $Fol | ls -Force }
if ($Obj)
{
$Obj | foreach {
if ($_.Attributes -match 'ReparsePoint') { ++$_measure.Links }
elseif ($_.Attributes -notmatch 'Directory')
{
Try { $_measure.Size += ($_ | gi -Force -Stream '*' | measure Length -Sum).Sum }
Catch { $_measure.Size += $_.Length }
Finally { ++$_measure.Files }
}
else { ++$_measure.Folders; calculate -Fol $_ }
}
}
} # /function::calculate
calculate -Obj $this.Object
return New-Object -TypeName 'PSObject' -Property $_measure
} # /measure
$sked += $rec
}
return $sked
}
$method['Clear'] = {
.{ param ([Parameter(Mandatory=$false)][string]$Mask)} @args
if ($Mask)
{
$this.List($Mask) | foreach { $_.Delete() }
$this.Wrapper.IconUpdate()
}
else { $this.Wrapper.Empty() }
}
$method['Measure'] = {
.{ param ([Parameter(Mandatory=$false)][string]$Mask)} @args
$res = @{Links = 0; Files = 0; Folders = 0; Size = 0}
$this.List($Mask) | foreach {
$item = $_.Measure()
$res.Links += $item.Links; $res.Files += $item.Files
$res.Folders += $item.Folders; $res.Size += $item.Size
}
return New-Object -TypeName 'PSObject' -Property $res
}
$bin = (New-Object -ComObject 'Shell.Application').Namespace(0xA)
$bin | Add-Member -MemberType 'ScriptMethod' -Name 'List' -Value $method.List
$bin | Add-Member -MemberType 'ScriptMethod' -Name 'Clear' -Value $method.Clear
$bin | Add-Member -MemberType 'ScriptMethod' -Name 'Measure' -Value $method.Measure
$bin | Add-Member -MemberType 'NoteProperty' -Name 'Wrapper' -Value (New-Object -TypeName 'shell32.ShellWrapper')
New-Variable -Name RecycleBin -Value $bin -Option Constant
Remove-Variable -Name 'method', 'bin', 'shell32_wrapper'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment