Organize photos and videos in nested directories, by year, month and day, to uncluter the root 'My Pictures'.

Usage
- Import photos using Windows Live Photo Gallery or similar to a given directory, for example 'My Pictures'.
- When importing, set the target folder name to 'Date Taken + Name', so photos are pre-organized in directories named like "2009-01-31".
- After photos are imported, open PowerShell, cd to the root folder of your photos and invoke this script.
- The end result is that all folders whose name start like 'yyyy-mm-dd' move to sub-folders, organized by year and month.

Granted, Windows Live Photo Gallery offers a similar view regardless of the actual folder structure but I find it easier to manage my files with a folder hierarchy like this on the disk.

PowerShell
Edit|Remove
# Organize photos and videos in nested directories, by year, month and day, to uncluter the root folder.
# Usage
# - Import photos using Windows Live Photo Gallery or similar to a given directory, for example 'My Pictures'.
# - When importing, set the target folder name to 'Date Taken + Name', so photos are pre-organized in directories named like "2009-01-31".
# - After photos are imported, open PowerShell, cd to the root folder of your photos and invoke this script.
# - The end result is that all folders whose name start like 'yyyy-mm-dd' move to sub-folders, organized by year and month.
#
# Granted, Windows Live Photo Gallery offers a similar view regardless of the actual folder structure but I find it easier to manage my files with a folder hierarchy like this on the disk.

# Process all files whose name looks like a date created by Windows Live Photo Gallery
$sources = Get-ChildItem -filter "????-??-??*"

# Process each file
foreach ($source in $sources) {

	# Create the target directory as year\month
	$year = $source.Name.Substring(0,4)
	$month = $source.Name.Substring(5,2)
	$targetDirName = join-path $year $month
	if (-not (test-path $targetDirName)) {
		$targetDir = new-item -type directory -path $targetDirName;
	}

	# Figure out the target directory name under the organized directory
	$targetPath = join-path $targetDirName $source.Name;

	# If the target directory already exists, create a unique name
	if (test-path $targetPath) {
		for ($i=1;$i -lt [Int32]::MaxValue; $i++) {
			$uniquePath = join-path $targetPath $i;
			if (-not (test-path $uniquePath)) {
				$targetPath = $uniquePath;
				break;
			}
		}
	}

	# Move the source directory to the target path
	write-host Moving [$source.Name] to [$targetPath]
	move-item $source.Name $targetPath
}