I’m lazy, I hate having to do the same thing twice. It’s boring. If there is something that needs to be done regularly I want it automated. That’s why I became a software developer.
Naturally: the cobbler’s kids have no shoes. I’m kept so busy making things better for my clients that I forget to take time to make things better for myself. Time to start changing that
In this case, I have a fairly simple problem: I take lots of pictures on my cell phone. My cell phone uploads the pictures to my OneDrive. I use OneDrive on all my machines. My Surface has a 256Gb SSD in it. There are about 127Gb of pictures on my OneDrive. See the issue?
My main workstation has a 4Tb external hard drive where I kept ‘stuff’ and it has a media folder where old pictures and videos are stored.
The requirements seem easy:
- all pictures in my Camera Roll folder on OneDrive need to be moved to my Camera Roll folder in my media archive.
- I also want video files (MP4) that are more than 5 days old to move as well.
- I’d also like to keep a log so I can tell that this is happening.
The way I chose to implement this (the title should get it away) was to write a very simple PowerShell script and then schedule it using Windows Scheduler.
Here is the script:
While this is easy, I had to look up this stuff so I don’t feel bad explaining it in detail. I’ll break it down step by step.
Before I get in to it though I want to point out that you can type each of the commands above in to the PowerShell command line to see what they do. You can even change things around to see what happens. Or you can load the script in to the PowerShell ISE and step through it with a debugger.
The first part of the script just counts how many files are going to be moved.
The very first line (after the comment) is just giving me a short cut to where I’m going to write my logging information.
Next get-childitem gets all the JPEGs in my camera roll. Get-childitem is also aliased as the old DOS “DIR” command or UNIX ‘ls’ command if you don’t want to type all of those letter. The list of files is passed on to where-object using a pipe command (the ‘|’ thing).
The where-object filters out pictures that are less than 30 days old and then passes them, or pipes them on to measure-object. Measure-object counts and measures stuff. In this case we just want the count. Notice that I have all the commands wrapped inside of parentheses? This allows us to get just the count output from the measure-object command and assign it to our $jpegCount variable.
The exact same process is used to get a count of video files in my camera roll. The ony differences are that we are looking mp4 files and we only want files more than 5 days old.
Next I make a custom date string by getting today’s date with get-date and passing it to ToString with a custom format string. I like formatting dates from greatest precedence to least precedence. It makes more sense. You don’t write Fifty five dollars two hundred do you? Then why do we write dates as April 27, 2017?
With our nicely formatted date and file counts we now update the log file with the information about how many files are about to be moved. Add-Content appends whatever you provide to the file you specify.
With the log file updated we’re now ready to move the files around. Moving the pictures looks just like getting the count. The differences are that we are not assigning the results to a variable so we don’t need the parentheses and we pass the filtered list of files to move-item instead of measure-object.
Moving the videos is the same process with the differences as explained before.
We now have our script that does the work. The last step is that we need to schedule the script to be run once a day. To do this run Task Scheduler as the administrator and create a new task. Here is how I do it:
- Window+Q to bring up Cortana and search for “Task Scheduler”
- Right click on “Task Scheduler” and choose “Run as Administrator”
- In Task Scheduler click on “Create Basic Task”
- Give it a name and click “Next”
- Set the trigger to daily and click “Next”
- Select a time for the job to run. I like to do things at 1am. Click “Next”
- Select “Start a program” and click “Next”
- Now we enter our actual program. In this case you can just type the entire command line in the main box. The command you want to type is:
PowerShell -noninteractive -file C:\Users\your user name\Documents\WindowsPowerShell\MoveOneDrivePictures.ps1
With obvious adjustments. When you’re done click “Next”
- You’ll be presented with a confirmation message b/c Task Scheduler is going to split things up for you. Just say “Yes”
- You’ll be presented with a summary of what you want scheduled. If you’re happy just click “Finish” and you’re done.
You can test our your job by right clicking on it and choosing “Run”. Just go see if the log file was created. If it was your job ran. Otherwise you have some debugging to do.
Overall this is not a horribly complex script or task, but it opens the door to other things. We’ll get in to those things soon.