Thursday, January 23, 2014

Fastest way for recursive folder deletion with PowerShell

I had a hard time to develop a script that remotely deletes some files, and when I finally put it in production I was surprised with the time it took to delete the folders. I tried researching a better method for recursively deleting folders but the best I could find was this post in the Microsoft´s Scripting Guy Blog. The only problem is that nobody worried about the efficiency of these methods, so that's what I'm talking about in this post.
Measuring the performance of a deletion method is tricky, as depending on the contents and attributes of the files some methods are not able to handle, and treating these details prior to delete may take more time than just deleting with another method, so after some tests I was able to create the following "generic force method" to get rid of a folder using PowerShell:

$folderToDelete = "C:\temp\test"

$ErrorActionPreference= 'silentlycontinue'
[]::delete($folderToDelete, $true)
$fso = New-Object -ComObject scripting.filesystemobject
if (Test-Path ($folderToDelete)) {
New-Item -ItemType directory -Path .\EmptyFolder
robocopy .\EmptyFolder $folderToDelete /mir
Remove-Item .\EmptyFolder
Remove-Item $folderToDelete

If you want, you can just use the above code to quickly get rid of your folders, but if you want to understand the code, continue reading =)

You may notice that I didn't use the "Remove-Item" cmdlet, first reason is because the -Recurse parameter doesn't work as expected until version 4, the other reason is that it was the method that took more time to delete a 17.5 GB test folder (22′ 27″).
Another strange thing you may notice was the robocopy command: Although it is designed to copy files, the /mir (mirroring an empty folder) parameter can be very useful to force the deletion of some things we get access denied errors with other commands, like "read-only" files and ownership issues. It's not that efficient (20′ 36″ for the same test folder) but is useful as it always deletes everything.
The FileSystemObject was also used, as it deletes (almost) everything in most cases. In the test folder case it was able to delete everything in 13′ 21″, but, as I said, it doesn't delete all files in every case, so using robocopy is still necessary.
Finally let's talk about the the .NET Framework System.IO.Directory class. This is the fastest method, but unfortunately it's also the one we get more errors... In the test case I was only able to delete everything with it after recursively removing the read-only attribute (Get-ChildItem $folderToDelete -Recurse | % { if($_.IsReadOnly){$_.IsReadOnly= $false}} ) but doing this the performance downgraded so much that it took a bit more than the FileSystemObject: 13′ 28″. Now, if I use this method combined with robocopy I get some advantage: 11′ 18″.
As you could see combining the methods was better than trying to fix the access issues, so why not using the fastest methods combined? This was what I did: Combined System.IO.Directory with FileSystemObject and got the folder deleted in 5′ 26″! Finally, I just added the robocopy command to ensure the folder will be cleaned up in all cases.

As you can see, depending on the case some methods can be better than others, but generally speaking, the commands I just brought to you can be the solution for performance in deleting folders with PowerShell.
Note: I haven´t tested in version 4 of PowerShell yet, so maybe Remove-Item can still be considered.

Monday, December 30, 2013

Restoring Chrome bookmarks

Bookmarks have never been the same since Google stopped having toolbars that synchronized with Google Bookmarks, but this is another story. Now if you want to have your bookmarks in your browser anywhere you NEED to use Chrome bookmarks, you’ll sign in to Chrome, ask it to sync your bookmarks and then you have it with you.
So, if you accidentally deleted your bookmarks, and don’t have a backup (if you haven’t exported your bookmarks to an html file) there’s still a way to recover them. You can find steps to do it in many internet sites and forums but what I’m going to tell you nobody says, it’s when you do these steps and Chrome continues to delete your bookmarks when it starts as it syncs with you google account.
As the start of the troubleshoot is already well explained by C.D. Crowder in I’m copying it here:
Google Chrome automatically backs up your bookmarks on a regular basis. While the frequency depends on how often you use the browser, odds are the most recent backup will contain your deleted bookmarks. The only problem is Chrome doesn't make these backups blatantly obvious or easy to access. You must know exactly where to look and which file to use. 
Finding Bookmark Backups 
Start by opening a new instance of Windows Explorer. Basically, just open any folder. All you need is the location bar at the top of the window. Copy the following line into the location bar and replace USERNAME with your own Windows username: 
C:\Users\USERNAME\AppData\Local\Google\Chrome\User Data\Default 
If you're not certain what your username is, open the Start menu and look at the top right side of the menu. Your name should be at the top if you're using Windows XP or later.
You'll see two bookmark files when the folder opens. The Bookmarks file contains all your current bookmarks. Bookmarks.bak contains the most recent backup of your bookmarks.
Just a comment here, if you notice both files have the same size, open these files with notepad and compare their contents, in case you see that both files contain the same contents (so that your .bak file is already backing up the new “bookmarks” file)  there’s still a hope if you’re running windows 7 or above, firstly close Chrome, and then you can right-click the bookmarks.bak file and click “properties”, after this click on “previous versions”. It will then do a search. It will have a version backed up of the last couple of days. Click on the most recent, and then hit “restore”. You will then have restored the backup of the backup file ;-) and you can continue here with the troubleshoot.
Before you proceed, check the date on the Bookmarks.bak file to ensure it was created before you deleted your bookmarks. If the file is newer, the bookmark cannot be restored. 
Restoring Chrome Bookmarks 
To prevent any possible problems, back up both files before proceeding. Simply select both files and press Ctrl + C. Minimize all windows to show your desktop. Click a blank space on the desktop and press Ctrl + V. This provides a backup of the original files should something go wrong.
Now, as I mentioned earlier, if you just delete the “bookmarks” file rename “bookmarks.bak” to “bookmarks” it won’t work as you’re synchronizing your bookmarks with your google account. I’ll show you how to solve it:
  1. Ensure that Chrome is not open.
  2. If you have Chrome in your smartphone, turn the cell phone off.
  3. Open both files in notepad (chose the option to open the file in an already installed software)
  4. You will need to preserve the line that starts with ”checksum” in the “bookmarks” file. you can delete everything after this line.
  5. Copy all the contents after this line of the “bookmarks.bak” file, paste on the “bookmarks” file and then save it.
  6. Open Chrome and voilĂ , your bookmarks are back to you.
After all this, you can start exporting your favorites to an html file, it will be much more easy to restore them later.