Scripting the Task Scheduler to Create System Restore Points

I ran into an interesting situation the other day: I had a hard drive that was going bad, and thankfully I had most of my data backed up on a schedule. However, before I removed the old hard drive, I wanted to log into the system to double-check a few settings. Unfortunately, several of the operating system files had become corrupted and the system wouldn't boot.

I didn't think that was a big deal, because I could try a system restore. However, I had forgotten that Windows 10 creates far less restore points than previously, so I had fewer to work with. In the end, I wasn't able to boot the system that final time.

Now that I have my newly rebuilt computer up and going, I set out to create a scheduled task that will create system restore points on a schedule. However, I wasn't content to create the task; I wanted to create the task using a batch file script so I could easily run the script to create the same task on any new systems that I might build.

It took me a while to get the script parameters the way that I wanted them, but the following one-line script achieves everything that I wanted to do. Note that you need run this script in an elevated command prompt, otherwise it might fail with an access denied error.

schtasks.exe /create /tn "Create Restore Point (MONTHLY)" /sc MONTHLY /d SUN /mo FIRST /st 05:00 /rl HIGHEST /ru "NT AUTHORITY\SYSTEM" /tr "PowerShell.exe -ExecutionPolicy Bypass -Command \"Checkpoint-Computer\" -Description \"AUTOMATIC-$(Get-Date -Format \"yyyyMMddHHmmss\")\" -RestorePointType \"MODIFY_SETTINGS\""

Here are the different parts of that script in detail, so you can modify them for your situation:

schtasks.exe This is Windows' command line application for managing scheduled tasks.
/create Specifies that we will be creating a scheduled task.
/tn "Create Restore Point (MONTHLY)" Specifies the name for the scheduled task.
/sc MONTHLY Specifies the schedule type, which could be MONTHLY, WEEKLY, DAILY, HOURLY, etc.
/d SUN These two parameters work together to specify how often the task runs, and the options for these values will depend on the schedule type. In this example, it is specifying the FIRST SUNDAY of each month.
/mo FIRST
/st 05:00 Specifies the starting time in 24-hour format.
/rl HIGHEST Specifies the "run level," which in this example is the highest level.
/ru "NT AUTHORITY\SYSTEM" Specifies the user account to run the task as, which in this case is "NT AUTHORITY\SYSTEM".
/tr "<<SEE BELOW>>" Specifies the command to run inside the task. The actual command in this example is somewhat complex, so I've broken it down in the following table. Note that this command needs to be within a pair of quotation marks; if you need to include quotation marks for the values inside this script, you will need to escape those characters as I have done in this example.

And here are the parameters for the task that is going to run as part of the task:

PowerShell.exe The application that we're running in this application is PowerShell.exe, because PowerShell has a cmdlet to create a restore point.
-ExecutionPolicy Bypass Specifies the execution policy, which in this example specifies that nothing will be blocked and there are no warnings or prompts.
-Command "Checkpoint-Computer" Specifies the PowerShell cmdlet that creates a system restore point, which takes the following two parameters.
-Description "AUTOMATIC-$(Get-Date -Format \"yyyyMMddHHmmss\")"

Specifies the description of the system restore point, which in this example invokes another PowerShell cmdlet to specify a date/time stamp that will show when the restore point was created. The restore points created by this task will look like "AUTOMATIC-20211201015150."

-RestorePointType "MODIFY_SETTINGS" Specifies the type of restore point, which could be APPLICATION_INSTALL, APPLICATION_UNINSTALL, DEVICE_DRIVER_INSTALL, MODIFY_SETTINGS, or CANCELLED_OPERATION.

That's about all there is to it. In a sense, this task is a bit of a script hack by invoking PowerShell cmdlets via the command line, but it works. And at the end of the day, that's all that matters.

Here are a few additional resources that provide more detail on the commands that I was using to create this script:

I hope this helps!