The working folder behind this site lives on one drive of one Windows 11 machine. That’s fine right up until the drive dies, so I wanted a weekly copy on a second drive that happens without me remembering to do it.
The standard recipe is robocopy plus Task Scheduler, both built into Windows with nothing to install. It mostly works as advertised. There are a few places where the usual version quietly misbehaves, and one step where Windows 11 rejects the credential it trains you to use everywhere else.
Problem one: a script that mirrors, and says so Link to heading
Robocopy’s /MIR makes the destination an exact copy of the source. It adds new files, updates changed ones, and deletes anything no longer in the source. Here’s the script, saved as C:\Scripts\weekly-backup.bat:
@echo off
set "SOURCE=E:\Projects\site-build"
set "DEST=D:\Backups\site-build"
set "LOGFILE=D:\Backups\backup-log.txt"
echo ==================================== >> "%LOGFILE%"
echo Backup started: %date% %time% >> "%LOGFILE%"
robocopy "%SOURCE%" "%DEST%" /MIR /R:3 /W:5 /NP /LOG+:"%LOGFILE%" /TEE
set "RC=%ERRORLEVEL%"
echo Backup finished: %date% %time% (exit code %RC%) >> "%LOGFILE%"
echo. >> "%LOGFILE%"
rem Robocopy: 0-7 = success, 8+ = something actually failed
if %RC% GEQ 8 exit /b 1
exit /b 0
What each switch is for:
/MIRmirrors the tree, deletions included. More on that below./R:3 /W:5retries a locked file three times, five seconds apart. Robocopy’s default is a million retries at 30 seconds each, which can leave a scheduled task hanging for days on one file that’s open./NPdrops the per-file percentage counters. Without it, the log fills up with progress noise./LOG+:appends to the log instead of overwriting it, so every run adds a timestamped entry you can check later./TEEalso echoes output to the console, which only matters when you run the script by hand.
The exit-code lines at the bottom are my addition, and they’re worth keeping. Robocopy doesn’t use 0 to mean success. A run that copied files returns 1, and Task Scheduler then shows “Last Run Result: 0x1”, which looks exactly like a failure. Converting 0–7 to 0 in the script means that when the task history shows an error, it really is one.
Two honest limitations:
- The retries only cover files locked briefly, such as something mid-save. A file held open all week, like a running database or an Outlook data file, will still fail and show up in the log.
- A mirror is not a history. If you delete something by accident on Monday, Sunday’s run deletes it from the backup as well. It protects you from a dead drive, not from your own mistakes. Problem four deals with that.
Run the script by double-clicking it once before you schedule anything. Check that the destination has a full copy and that the log shows a clean run.
Problem two: scheduling it so it actually runs Link to heading
Setting up the task is routine:
- Open
taskschd.mscand choose Create Basic Task. - Give it a name, set a Weekly trigger, and pick a day and time when the PC is usually on.
- Set the action to Start a program and point it at
C:\Scripts\weekly-backup.bat.
The defaults are the problem. Open the finished task’s Properties and there are a few settings worth reviewing:
- Conditions → “Start the task only if the computer is on AC power”: clear this on a laptop. Otherwise a laptop on battery skips the backup without telling you.
- Conditions → “Wake the computer to run this task”: this helps if the PC is usually asleep at the scheduled time. It also depends on wake timers being allowed in the power plan (Power Options → advanced settings → Sleep → Allow wake timers). If they’re disabled, the checkbox does nothing.
- Settings → “Run task as soon as possible after a scheduled start is missed”: if the PC was off on Sunday night, the backup runs the next time the machine is available instead of waiting another week. This one setting covers most of the “what if it was off” worry.
And then there’s the setting that everyone reaches for next.
Problem three: the PIN isn’t a password Link to heading
By default a task runs only while you’re logged on. The obvious fix is to go to the General tab and select “Run whether user is logged on or not”. When you click OK, Task Scheduler asks for your account credentials.
On Windows 11 you’d naturally type your PIN. It gets rejected.
The reason is that a Windows Hello PIN isn’t a shorter password. It’s tied to that one device and unlocks a key held locally in the TPM. It never acts as your account’s actual credential, which is the whole security point: a leaked PIN is useless on any other machine.
“Run whether user is logged on or not” needs the opposite. Task Scheduler has to store a credential it can use to start a session later with nobody at the keyboard. That means your real account password, which on a Microsoft account is your Microsoft account password. The prompt doesn’t explain any of this. It just says the credentials are wrong, on the one screen in Windows 11 where the PIN you use everywhere else doesn’t count.
You have two ways out:
- Use the real password. If you haven’t typed it in two years, reset it at account.microsoft.com first. Keep in mind that the task stores a copy, so if you change the password later, the task starts failing until you re-enter it in its properties.
- Leave the default. Keep “Run only when user is logged on” and turn on “run as soon as possible after a missed start” from problem two. On a machine that’s used most days, the worst case is a backup that runs a day late. There’s nothing stored that can go stale.
For a home or small-office PC, the second option is the sensible one. That’s what I went with.
Problem four: when a single mirror isn’t enough Link to heading
If a mirror that overwrites itself every week makes you nervous, the alternative is dated snapshots. Each run copies to a new folder named for the date, and old snapshots are pruned.
The version of this that circulates online builds the date by parsing date /t. That depends on the machine’s regional format. On a US-format machine it returns something like Thu 09/24/2026. On an Indian-format machine it returns 24-09-2026, so the parsing produces garbage or nothing at all. Letting PowerShell format the date avoids the problem:
@echo off
set "SOURCE=E:\Projects\site-build"
set "DESTROOT=D:\Backups\site-build"
for /f %%i in ('powershell -NoProfile -Command "Get-Date -Format yyyy-MM-dd"') do set "DATESTAMP=%%i"
robocopy "%SOURCE%" "%DESTROOT%\%DATESTAMP%" /E /R:3 /W:5 /NP
rem Prune snapshot folders older than 60 days
forfiles /p "%DESTROOT%" /d -60 /c "cmd /c if @isdir==TRUE rmdir /s /q @path" 2>nul
A few caveats:
- Test the pruning line before trusting it. That last line runs
rmdir /s /qautomatically. Replacermdir /s /q @pathwithecho @pathon the first run and check what it would delete.forfilesgoes by each folder’s last-modified date, not by the date in its name. - Budget the disk space. Sixty days of weekly snapshots is roughly nine full copies of the folder. That’s trivial for a code folder and painful for a photo library.
- Pick one approach. Mirror or snapshots, not both pointed at the same place.
Why this is the job Link to heading
None of this is hard, and I won’t pretend otherwise. What’s worth noticing is where the time actually goes. The overall design is fine. It’s the defaults and the quiet assumptions that break it: a success code that looks like a failure, a date format that depends on locale, a laptop that skips the job on battery, and a PIN that works everywhere except the one place it’s needed. That’s most of small-business IT in miniature. The job is to find why a step fails silently, pick the fix that suits how the business actually runs rather than the most thorough-sounding one, and write it down so it still works after the next password change.
Next up: a second drive on the same desk still shares a power supply and a burglar with the first one, so the next post is about getting a copy off this machine entirely.