1

Here (Listing files in recycle bin) I've found a @Smile4ever post saying how to get the original location for the files in recycle bin:

(New-Object -ComObject Shell.Application).NameSpace(0x0a).Items()
|select @{n="OriginalLocation";e={$_.ExtendedProperty("{9B174B33-40FF-11D2-A27E-00C04FC30871} 2")}},Name
| export-csv -delimiter "\" -path C:\Users\UserName\Desktop\recycleBinFiles.txt -NoTypeInformation

(gc C:\Users\UserName\Desktop\recycleBinFiles.txt | select -Skip 1)
| % {$_.Replace('"','')}
| set-content C:\Users\UserName\Desktop\recycleBinFiles.txt

I'd like to copy them somewhere (in case I've been told that some of them were not to be deleted and someone empty recycle bin).

Here (https://superuser.com/questions/715673/batch-script-move-files-from-windows-recycle-bin) I've found a @gm2 post for copying them

$shell = New-Object -ComObject Shell.Application  
$recycleBin = $shell.Namespace(0xA) #Recycle Bin  
$recycleBin.Items() | %{Copy-Item $_.Path ("C:\Temp\{0}" -f $_.Name)}   

And they work fine, but I'd need something more.

I don't know anything about powershell, but what I'd like to do would be: for each file in Recycle bin to create its original location folder in the backup folder C:\Temp and to copy the file there (so I won't have the problem of more files with the same name).

And then to zip that C:\Temp.

Is there a way foir doing it? Thanks!

solquest
  • 65
  • 10

1 Answers1

1

You should be able to do it like this:

# Set a folder path INSIDE the C:\Temp folder to collect the files and folders
$outputPath = 'C:\Temp\RecycleBackup'
# afterwards, a zip file is created in 'C:\Temp' with filename 'RecycleBackup.zip'

$shell = New-Object -ComObject Shell.Application  
$recycleBin = $shell.Namespace(0xA)
$recycleBin.Items() | ForEach-Object {
    # see https://learn.microsoft.com/en-us/windows/win32/shell/shellfolderitem-extendedproperty
    $originalPath = $_.ExtendedProperty("{9B174B33-40FF-11D2-A27E-00C04FC30871} 2")
    # get the root disk from that original path
    $originalRoot = [System.IO.Path]::GetPathRoot($originalPath)

    # remove the root from the OriginalPath
    $newPath = $originalPath.Substring($originalRoot.Length)

    # change/remove the : and \ characters in the root for output
    if ($originalRoot -like '?:\*') {  
        # a local path.  X:\ --> X
        $newRoot = $originalRoot.Substring(0,1)
    }
    else {                             
        # UNC path.  \\server\share --> server_share
        $newRoot = $originalRoot.Trim("\") -replace '\\', '_'   
        #"\"# you can remove this dummy comment to restore syntax highlighting in SO
    }

    $newPath = Join-Path -Path $outputPath -ChildPath "$newRoot\$newPath"
    # if this new path does not exist yet, create it
    if (!(Test-Path -Path $newPath -PathType Container)) {
        New-Item -Path $newPath -ItemType Directory | Out-Null
    }

    # copy the file or folder with its original name to the new output path
    Copy-Item -Path $_.Path -Destination (Join-Path -Path $newPath -ChildPath $_.Name) -Force -Recurse
}

# clean up the Com object when done
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($shell) | Out-Null
[System.GC]::Collect()
[System.GC]::WaitForPendingFinalizers()
$shell = $null

The following code needs PowerShell version 5

# finally, create a zip file of this RecycleBackup folder and everything in it.
# append a '\*' to the $outputPath variable to enable recursing the folder
$zipPath = Join-Path -Path $outputPath -ChildPath '*'
$zipFile = '{0}.zip' -f $outputPath.TrimEnd("\")
#"\"# you can remove this dummy comment to restore syntax highlighting in SO

# remove the zip file if it already exists
if(Test-Path $zipFile -PathType Leaf) { Remove-item $zipFile -Force }
Compress-Archive -Path $zipPath -CompressionLevel Optimal -DestinationPath $zipFile -Force

To create a zip file in PowerShell below version 5

If you do not have PowerShell 5 or up, the Compress-Archive is not available.
To create a zip file from the C:\Temp\RecycleBackup you can do this instead:

$zipFile = '{0}.zip' -f $outputPath.TrimEnd("\")
#"\"# you can remove this dummy comment to restore syntax highlighting in SO

# remove the zip file if it already exists
if(Test-Path $zipFile -PathType Leaf) { Remove-item $zipFile -Force }
Add-Type -AssemblyName 'System.IO.Compression.FileSystem'
[System.IO.Compression.ZipFile]::CreateFromDirectory($outputPath, $zipFile) 

Of course, you can also use a third party software like 7Zip for this. There are plenty of examples on the net how to use that in Powershell like for instance here

As per your last request to remove the 'RecycleBackup' folder after the zip is created

Remove-Item -Path $outputPath -Recurse -Force

Hope that helps

Theo
  • 57,719
  • 8
  • 24
  • 41
  • Thank you so much! On my pc it works perfectly, while on the pc where I need it, it creates the backup, but while zipping I get the error: – solquest Jul 09 '19 at 14:21
  • Compress-Archive : The term 'Compress-Archive' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again. At C:\XXX\backup_deleted_files.ps1:48 char:1 + Compress-Archive -Path $zipPath -CompressionLevel Optimal -DestinationPath $zipF ... + ~~~~~~~~~~~~~~~~ + CategoryInfo : ObjectNotFound: (Compress-Archive:String) [], CommandNotFoundException + FullyQualifiedErrorId : CommandNotFoundException I created the zip manually without problems – solquest Jul 09 '19 at 14:21
  • what is missing? Thanks! – solquest Jul 09 '19 at 14:22
  • one last thing: once the zip file is created (but only if it's created) would be useful to delete (permanently, not moving it in recycle bin) the C:\Temp\RecycleBackup, for not occupying too many GB... Thanks! – solquest Jul 09 '19 at 15:09
  • @solquest I have updated my answer. Apparently you are working with a Powershell version below 5.0 (`Compress-Archive` is available as of PowerShell version 5), so I added alternative code. I have also added code to remove the C:\Temp\RecycleBackup folder afterwards. – Theo Jul 09 '19 at 18:26