# Exercise: Back Up While You Sleep

Turn a backup script that only works at the keyboard into one a scheduled task can run every evening at 6 PM, with no questions, full paths, a dated log and a transcript, a robocopy mirror that never mirrors an empty folder and can rehearse, and an honest exit code, then build the task that runs it, while a Pester check runs your script the way the task would.

Journeyman · PowerShell · Operating System · Updated November 10, 2026

This is the chapter in one job: a backup of your school work that happens every evening, whether you remember or not, and tells you the truth about how it went. `Backup-SchoolWork.ps1` copies a `school-work` folder with robocopy, but only when you run it yourself, from its own folder, and answer its question. Your job is to make it safe to run with nobody there, then build the scheduled task that runs it at 6 PM. A Pester check runs your script the way a task would, from another folder with nobody to answer, and tells you which jobs are done.

Windows only: robocopy and scheduled tasks are part of Windows.

## Get the exercise code

Open this lesson's GitHub repository, [github.com/ask-codey/exercise-powershell-back-up-while-you-sleep](https://github.com/ask-codey/exercise-powershell-back-up-while-you-sleep), also linked from the **Exercise** box beside the lesson. Click **Code**, then **Download ZIP**, and unzip it into your `terminal-practice` folder. Or clone it with Git.

The folder holds:

- `Backup-SchoolWork.ps1`: the backup script, with jobs 1 to 7 as numbered comments.
- `New-BackupTask.ps1`: builds the scheduled task, with jobs 8 to 10. It hands the task back and registers nothing.
- `school-work/`: practice files to back up.
- `Check.Tests.ps1`: the check. You don't need to change it.

## What to do

Open PowerShell in the exercise folder, the one with `Check.Tests.ps1` in it, and open it in VS Code with `code .`. First, test the script the way *Scripts That Run Without You* did, with the task's own command:

```powershell
pwsh -NoProfile -NonInteractive -File .\Backup-SchoolWork.ps1
$LASTEXITCODE
```

```text
Read-Host: C:\Users\Sam\terminal-practice\exercise-powershell-back-up-while-you-sleep\Backup-SchoolWork.ps1:16
Line |
  16 |  $answer = Read-Host 'Back up school-work now? (y/n)'
     |            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     | PowerShell is in NonInteractive mode. Read and Prompt functionality is not available.

0
```

Nothing was backed up, and the exit code says it worked. Then, one job at a time:

1. **Full paths.** `$Source` and `$Destination` default to `school-work` and `backup` in the script's own folder, built from `$PSScriptRoot`.
2. **No one to answer.** The question goes.
3. **A log.** A `Write-Log` function adds a dated line to `logs\backup.log` beside the script, and prints it too.
4. **A transcript.** `Start-Transcript` records each run in `logs\last-run.txt`.
5. **Never mirror nothing.** A missing or empty source folder is logged, and the script stops with exit code 1 before robocopy runs.
6. **The mirror.** robocopy mirrors with `/MIR /R:2 /W:5 /NP`, and `-Rehearse` adds `/L`.
7. **An honest exit code.** robocopy's code below 8 is exit 0, and 8 or more is exit 1, with a log line either way.
8. **The task.** Jobs 8 to 10 are in `New-BackupTask.ps1`: a trigger for every day at 6 PM, an action that runs `pwsh.exe -NoProfile -NonInteractive -File` with the script's full path, and settings for a laptop.

The README in the folder gives each job's messages word for word. Try your script as you go, rehearsal first: `.\Backup-SchoolWork.ps1 -Rehearse`, then `.\Backup-SchoolWork.ps1`, then `Get-Content .\logs\backup.log`.

## Check your work

The check uses Pester. If you haven't installed it yet, install it once:

```powershell
Install-PSResource Pester
```

Then, from the exercise folder:

```powershell
Invoke-Pester
```

At first most tests fail. That's expected: each job you finish turns its tests green. A failing test names the job and says what to look at, for example *Expected 1, because robocopy can't copy into a file and ends with 16. Job 7 turns 8 or more into exit 1*. The check copies your script into a throwaway folder with made-up school work for every test, and runs it from another folder with `-NonInteractive`, so your own `school-work`, `backup` and `logs` are never touched. It builds your task and looks at it; nothing is registered on your computer.

If PowerShell says the check can't be loaded because it is not digitally signed, Windows has marked the downloaded files as coming from the internet: from the exercise folder, run `Get-ChildItem -Recurse | Unblock-File` once, then `Invoke-Pester` again.

## Hints

- **The task's folder isn't yours.** A task starts in `C:\Windows\System32`, so every path starts from `$PSScriptRoot` (*Scripts That Run Without You*).
- **Write-Log prints its line as well as saving it.** That's how the transcript gets it too.
- **An empty folder.** `Get-ChildItem` on an empty folder gives back nothing, and `-not` turns nothing into True.
- **Read the exit code at once.** `$LASTEXITCODE` changes with the next program that runs, so keep it in a variable right after robocopy (*Backups That Work: `robocopy`*).
- **Settings have switches.** `New-ScheduledTaskSettingsSet` has one switch for each of the three laptop settings (*Scheduled Tasks*).

## When you're done

Every test is green, and Pester's last line says:

```text
Tests Passed: 17, Failed: 0, Skipped: 0, Inconclusive: 0, NotRun: 0
```

Rehearse, back up twice, and read the log. `| Out-Null` hides robocopy's report, which `logs\last-run.txt` keeps anyway:

```powershell
.\Backup-SchoolWork.ps1 -Rehearse | Out-Null
.\Backup-SchoolWork.ps1 | Out-Null
.\Backup-SchoolWork.ps1 | Out-Null
Get-Content .\logs\backup.log
```

```text
2026-11-09 08:27:23 Rehearsal started: C:\Users\Sam\terminal-practice\exercise-powershell-back-up-while-you-sleep\school-work to C:\Users\Sam\terminal-practice\exercise-powershell-back-up-while-you-sleep\backup
2026-11-09 08:27:23 Rehearsal finished (robocopy exit code 1)
2026-11-09 08:27:24 Backup started: C:\Users\Sam\terminal-practice\exercise-powershell-back-up-while-you-sleep\school-work to C:\Users\Sam\terminal-practice\exercise-powershell-back-up-while-you-sleep\backup
2026-11-09 08:27:24 Backup finished (robocopy exit code 1)
2026-11-09 08:27:24 Backup started: C:\Users\Sam\terminal-practice\exercise-powershell-back-up-while-you-sleep\school-work to C:\Users\Sam\terminal-practice\exercise-powershell-back-up-while-you-sleep\backup
2026-11-09 08:27:24 Backup finished (robocopy exit code 0)
```

The rehearsal copied nothing, the first backup copied the files (1), and the second had nothing to do (0): three good nights. Your dates and times will be your own. The README's last section shows how to register the task on your own PC if you'd like it to run every evening for real; that part changes your computer, so it's yours to choose.

## Submit your exercise

The exercise is how you finish this lesson. When your work is done, put it on GitHub in a repo of your own, then submit that repo's address here.

1. On GitHub, click **+**, then **New repository**. Name it (for example `exercise-powershell-back-up-while-you-sleep`), choose **Public**, and click **Create repository**. Leave out the README: your folder already has one.
2. In a terminal in your exercise folder (PowerShell works), send your work to your new repo. If you downloaded the ZIP:

   ```powershell
   git init -b main
   git add .
   git commit -m "My solution"
   git remote add origin https://github.com/your-name/exercise-powershell-back-up-while-you-sleep.git
   git push -u origin main
   ```

   If you cloned the starter instead, point your copy at your own repo, then commit and push:

   ```powershell
   git remote set-url origin https://github.com/your-name/exercise-powershell-back-up-while-you-sleep.git
   git add .
   git commit -m "My solution"
   git push -u origin main
   ```

3. Paste your repo's address, such as `https://github.com/your-name/exercise-powershell-back-up-while-you-sleep`, into **Submit your exercise** on this page. The site checks that the repo is public and holds your commits, and then the lesson is complete.

Changed something after you submitted? Push it, and submit again: your latest submission is the one that counts.

## So what

A backup you'd forget, run by Windows every evening, that writes down what it did and says so when it fails: that's a script working for you while you sleep.

## Key terms

- [Scheduled Task](https://www.ask-codey.com/glossary/scheduled-task)
- [robocopy](https://www.ask-codey.com/glossary/robocopy)
- [Start-Transcript](https://www.ask-codey.com/glossary/start-transcript)
- [Log File](https://www.ask-codey.com/glossary/log-file)
- [Exit Code](https://www.ask-codey.com/glossary/exit-code-operating-system)
- [$PSScriptRoot](https://www.ask-codey.com/glossary/psscriptroot)

## Related

- [Scheduled Tasks](https://www.ask-codey.com/lessons/powershell-scheduled-tasks)
- [Scripts That Run Without You](https://www.ask-codey.com/lessons/powershell-unattended-scripts)
- [Backups That Work: \`robocopy\`](https://www.ask-codey.com/lessons/powershell-robocopy)

Source: https://www.ask-codey.com/lessons/exercise-powershell-back-up-while-you-sleep
