Search code examples
powershellpowershell-4.0recycle-bin

PowerShell get deleted files of a folder


I try get the deleted files of a folder using Get-ChildItem and Trash but its not working so well. In trash I can get the file, but i dont know how discover what file is of the folder that I executed the script.

Get-ChildItem -Recurse -File #Can`t get deleted files

#I get the deleted files, but I dont know what folder they come
$Shell = New-Object -ComObject "Shell.Application"
($Shell.NameSpace(0xa)).items()

Solution

  • The NameSpace method returns a Folder object which provides a GetDetailsOf method you can use to retrieve details about each member of Items:

    New-Variable -Name 'ssfBITBUCKET'                       -Option Constant -Value 0x0A;
    New-Variable -Name 'BitBucketDetails_Name'              -Option Constant -Value 0;
    New-Variable -Name 'BitBucketDetails_ParentPath'        -Option Constant -Value 1;
    New-Variable -Name 'BitBucketDetails_DeletionTimeText'  -Option Constant -Value 2;
    New-Variable -Name 'BitBucketDetails_SizeText'          -Option Constant -Value 3;
    New-Variable -Name 'BitBucketDetails_Type'              -Option Constant -Value 4;
    New-Variable -Name 'BitBucketDetails_LastWriteTimeText' -Option Constant -Value 5;
    New-Variable -Name 'BitBucketDetails_CreationTimeText'  -Option Constant -Value 6;
    New-Variable -Name 'BitBucketDetails_LastAccessTimeText'-Option Constant -Value 7;
    New-Variable -Name 'BitBucketDetails_AttributesText'    -Option Constant -Value 8;
    
    $application = New-Object -ComObject 'Shell.Application';
    $bitBucket = $application.NameSpace($ssfBITBUCKET);
    
    foreach ($deletedItem in $bitBucket.Items())
    {
        New-Object -TypeName 'PSObject' -Property @{
            # Same as $deletedItem.Name
            Name =               $bitBucket.GetDetailsOf($deletedItem, $BitBucketDetails_Name);
            ParentPath =         $bitBucket.GetDetailsOf($deletedItem, $BitBucketDetails_ParentPath);
            DeletionTimeText =   $bitBucket.GetDetailsOf($deletedItem, $BitBucketDetails_DeletionTimeText);
            Size =               $deletedItem.Size;
            SizeText =           $bitBucket.GetDetailsOf($deletedItem, $BitBucketDetails_SizeText);
            # Same as $deletedItem.Type
            Type =               $bitBucket.GetDetailsOf($deletedItem, $BitBucketDetails_Type);
            LastWriteTime =      $deletedItem.ModifyDate;
            LastWriteTimeText =  $bitBucket.GetDetailsOf($deletedItem, $BitBucketDetails_LastWriteTimeText);
            CreationTimeText =   $bitBucket.GetDetailsOf($deletedItem, $BitBucketDetails_CreationTimeText);
            LastAccessTimeText = $bitBucket.GetDetailsOf($deletedItem, $BitBucketDetails_LastAccessTimeText);
            AttributesText =     $bitBucket.GetDetailsOf($deletedItem, $BitBucketDetails_AttributesText);
            IsFolder =           $deletedItem.IsFolder();
            BitBucketPath =      $deletedItem.Path;
        };
    }
    

    ssfBITBUCKET is from the ShellSpecialFolderConstants enumeration. On my Windows 10 system set to the en-US culture, when a BitBucketDetails_*TimeText constant is passed to GetDetailsOf() it returns not a DateTime instance but a timestamp in the form of a String where the year, month, and day are each preceded by a left-to-right mark ([Char] 0x200E) and the time is preceded by a right-to-left mark ([Char] 0x200F) followed by a left-to-right mark.

    I determined the BitBucketDetails_* constants myself since I didn't find them documented anywhere, but according to this answer you can query for them by passing $null as the first parameter to GetDetailsOf(). Thus, you can keep querying the column names from the bit bucket namespace until it starts returning empty Strings like this...

    New-Variable -Name 'ssfBITBUCKET' -Option Constant -Value 0x0A;
    
    $application = New-Object -ComObject 'Shell.Application';
    $bitBucket = $application.NameSpace($ssfBITBUCKET);
    
    for ($column = 0; -not [String]::IsNullOrEmpty(($details = $bitbucket.GetDetailsOf($null, $column))); $column++)
    {
        New-Object -TypeName 'PSObject' -Property @{
            Column = $column;
            Name = $details;
        };
    }
    

    ...which outputs this on my system...

    Column Name
    ------ ----
         0 Name
         1 Original Location
         2 Date Deleted
         3 Size
         4 Item type
         5 Date modified
         6 Date created
         7 Date accessed
         8 Attributes
         ...