Previously I posted a way to save images from Windows Spotlight manually – but who wants that hassle?
So, to save you time, I’ve scripted this with PowerShell. This script is likely to evolve over time, as Microsoft are likely to change how the software works. Perhaps one day they’ll give us the save button on the lock screen, like has been requested by many. For now, here’s a way to do it.
First off, save the script below (right-click, save as).
The script itself can be run from any folder – you’ll need to right-click it and “Run with PowerShell”.
If your system doesn’t respond to the queue, you may have to set your execution policy to “UnRestricted”.
This can be done by opening PowerShell (found in the Start Menu), and entering the command
Set-Executionpolicy -Scope CurrentUser -ExecutionPolicy UnRestricted
The script looks like this:
<# Source file locations #>
$sourcesubdirectory="\Packages\Microsoft.Windows.ContentDeliveryManager_cw5n1h2txyewy\LocalState\Assets"
$sourcepath= $env:LOCALAPPDATA + $sourcesubdirectory
$sourceitems=$sourcepath+"\*"
<# Output file locations #>
$outputsubdirectory="\Pictures\Spotlight"
$outputpath = $env:USERPROFILE + $outputsubdirectory
<# Create output path if it doesn't exist already #>
if(!(Test-Path -Path $outputpath)){New-Item -ItemType directory -Path $outputpath}
<# Copy all files from last two days #>
$EarliestModifiedTime = (Get-date).AddDays(-2)
Get-ChildItem $sourcepath |? { $_.LastWriteTime -gt $EarliestModifiedTime } | Copy-Item -Destination $outputpath
<# Rename files #>
#Prefix name with DateTime, shorten original name to 6 characters, add jpg extension
Get-ChildItem $outputpath -exclude "*.jpg" | Rename-Item -NewName {$_.CreationTime.toString("yyyy.MM.dd_HH.mm") + " " + $_.name.Substring(0,6) + ".jpg"} -ErrorAction SilentlyContinue
<# Remove files not renamed (in the case of naming conflicts) #>
Get-ChildItem $outputpath -exclude "*.jpg" | Remove-Item -ErrorAction SilentlyContinue
<# Remove small files, in case of icons loading in folder #>
Get-ChildItem $outputpath |?{$_.PSIsContainer -eq $false -and $_.Length -lt 1300KB}|?{Remove-Item $_.FullName}
<# Open directory of copied items #>
explorer $outputpath
Let’s look at that in detail, shall we?
In the section ‘Source file locations’ we use Windows very own environment variables to give us the location of the files – that way this works for any user, not just one. We combine the strings to give us a final source to look at.
In ‘Output file locations’, we use environment variables to define where we’ll copy the files to. We ‘Test-Path’ to see if the output folder exists (it’ll be a folder named “Spotlight” in your Pictures folder), and we’ll create it if it doesn’t. The ‘if(!” in this part means ‘if false’, or ‘not there’. If it’s there (true), we’ll move on.
Next, we’ll set today’s date minus two days as the oldest file we want. This allows us to just copy files from the day before yesterday onwards, in case we remember an image that we haven’t saved yet. Using that date, we’ll copy those files that fit the criteria.
We’ll then rename the files that we copied, using the date and time they were created (<code>$_CreationTime.toString(“yyyy.MM.dd_HH.mm”)</code>, the first 6 characters of the original name (they’re pretty long names by default), and we’ll add a “.jpg” extension to the end of the name so we can actually use them. If there are any naming conflicts (which theoretically won’t happen if you move the files you save to your own save folder), the action on error (-ErrorAction) is to just carry on (SilentlyContinue).
In the event of a naming conflict, we’ll delete any files that didn’t get renamed (anything that isn’t a .jpg file). Then, just in case Microsoft stored low-resolution copies of the images or icons for apps in the folder (which they occasionally do – Flipboard and Minecraft show up a lot), we’ll delete anything less than 1300KB in size.
Lastly, we’ll call Windows Explorer to open the folder we put the files in. This way we can easily decide which ones we want to keep.