4

One of the hardest things I've had to do is access Windows APIs with PowerShell. I want to erase the Recycle Bin using the API in Shell32.dll. There are other ways of doing it, but they are typically bypassing the normal Windows processes and in this case, I want to do it the "right" way.

2 Answers2

4

After a few hours, I came up with this.

$TypeDefinition=@"
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);
    }

    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 function here
        public uint Empty() {
            uint ret = RecycleBin.SHEmptyRecycleBin(IntPtr.Zero, null, RecycleFlags.SHERB_NOCONFIRMATION | RecycleFlags.SHERB_NOPROGRESSUI | RecycleFlags.SHERB_NOSOUND);
            return ret;
        }

        // Occurs on destruction of the Wrapper
        ~ShellWrapper() {
            Dispose();
        }

    } //Wrapper class
}
"@
Add-Type -TypeDefinition $TypeDefinition -PassThru | out-null
$RecycleBin=new-object Shell32.ShellWrapper

$RecycleBin.Empty()
  • Does not work for me on windows 10 running elevated or not. 2147549183 and then after a few times, it errors saying that shell32.RecycleFlags already exists. – rjt Oct 23 '17 at 02:23
  • @rjt, can you give me more details about your system? I tested it on Windows 10 Enterprise x64 Version 1607, no domain membership, and it works perfectly in an elevated PowerShell session. – Slogmeister Extraordinaire Nov 02 '17 at 18:10
  • Domain Joined. Winver 1703 and then1709? Will get more info when i am at machine. – rjt Nov 20 '17 at 19:08
  • It works for me on a domain joined machine. But, I have administrator privileges on the workstation, even though I'm not running it elevated. You can't run it twice in the same PowerShell session because of the Add-Type statement. – Slogmeister Extraordinaire Oct 09 '18 at 17:40
0

How about this? Does not reset any permissions, works for all users and across all drives. I tested it on 2012 R2+

$dis = gwmi Win32_LogicalDisk -Filter 'DriveType=3' | select -ExpandProperty DeviceID
$rec = @()

foreach ($d in $dis)
{
    $rec += gci "$d\`$Recycle.Bin" -Force
}


foreach ($r in $rec)
{
    gci $r.FullName -Force -Recurse | rm -Force -Confirm:$false
} 
Guest
  • 1