# Exercise: Fewer Keystrokes

Finish Grandma's photo book the fast way, setting PSReadLine up with a list view and a longer memory, fixing a long command with keys, finding an old command in a saved history, and writing one-line commands with && and || that a Pester check runs where the first step works and where it fails.

Journeyman · PowerShell · Updated November 10, 2026

Grandma's 80th-birthday photo book is nearly done: one lake photo still needs an edited copy, the edits need a backup, and somewhere in August's history is the zip command you'll want again. The folders are four levels deep, so this is where the chapter's keys and checks pay off. It's the same shape as a lot of real work: an IT tech repeating a fix on twenty PCs, a developer rerunning a long command with one word changed, anyone who has to be sure step one worked before step two. You'll do eight small tasks, and a check tells you which are done.

## Get the exercise code

Open this lesson's GitHub repository, [github.com/ask-codey/exercise-powershell-fewer-keystrokes](https://github.com/ask-codey/exercise-powershell-fewer-keystrokes), 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:

- `photo-book`: the photo book project, with `originals`, `edited`, `book\page-order.txt` and a `backup` folder. The photos are small practice files with photo names.
- `saved-history.txt`: a copy of Sam's saved PowerShell history from August, the kind of file `(Get-PSReadLineOption).HistorySavePath` names.
- `fast-settings.ps1`, `backup-line.txt`, `fallback-line.txt` and `answers.txt`: for you to finish.
- `README.md`: the eight tasks, word for word.
- `Check.Tests.ps1`: the check. You don't need to change it.

## What to do

Open PowerShell 7 in the exercise folder, the one with `Check.Tests.ps1` in it, and run every command from there. Use the chapter's keys as you go: they're the point. Then do the eight tasks in the folder's `README.md`:

1. **Predictions as a list.** In `fast-settings.ps1`, the `Set-PSReadLineOption` line for the list view.
2. **A longer memory.** In `fast-settings.ps1`, the line for 10000 commands. Try both with `. .\fast-settings.ps1`; they last until you close the window.
3. **The lake photo.** Make the `lake` folder, paste the README's long `Copy-Item` line, and fix its destination with Ctrl+Left instead of retyping it.
4. **The zip that's still there.** Find Sam's command that made `backup\birthday-edits.zip` in `saved-history.txt`, and write it after `4)` in `answers.txt`.
5. **Back up, and only then say so.** One line in `backup-line.txt`: copy the edited photos into `backup`, then print `Backup done` only if that worked.
6. **Read the page order, or else say so.** One line in `fallback-line.txt`: show `page-order.txt`, or print `No page order yet` if that fails.
7. **A program's number.** The exit code of `where.exe photo-resizer`, after `7)`.
8. **Worked, or True?** What `$?` shows right after `Test-Path` on a missing file, after `8)`.

## Check your work

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

```powershell
Install-PSResource Pester
```

Then, from the exercise folder:

```powershell
Invoke-Pester
```

At first all eight tests fail. That's expected: each task you finish turns its test green. A failing test says which task it is, what it expected and what it found.

The check never changes your PSReadLine settings: it only reads which settings `fast-settings.ps1` asks for. It runs your lines from tasks 5 and 6 in throwaway copies of `photo-book`, once where the first command can work and once where it can't, so a line joined with `;` instead of `&&` or `||` shows up even if it looked right when you tried it.

If PowerShell says the check can't be loaded because running scripts is disabled or the file 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. *Why a Script Won't Run: The Execution Policy* explains what that does.

## Hints

- **Settings read back.** After `. .\fast-settings.ps1`, `Get-PSReadLineOption | Select-Object PredictionViewStyle, MaximumHistoryCount` shows whether they took, as *Predictions and History, Fully Used* shows. Write `10000` without a comma.
- **Where Ctrl+Left stops.** A word ends at a space, `\`, `-` or `.`, as *Keyboard Shortcuts at the Prompt* shows. From the end of task 3's line, the stops are `jpg`, `edit`, then `IMG_0731`.
- **Search for what only the right line has.** Two lines zip the birthday photos; only one makes `birthday-edits.zip`, with an *s*. *Finding Text: Select-String* shows how.
- **Read the marks aloud.** `&&` is "and then, if it worked", `||` is "or else", as *Did It Work? `$?`, `$LASTEXITCODE`, `&&` and `||`* explains.
- **Check right away.** `$?` and `$LASTEXITCODE` describe the command right before them, so run them on the very next line.
- **Getting a line into a file.** Open it in an editor (`edit backup-line.txt`, from *Editing in the Terminal: edit*), paste the line under the comment, and save.

## When you're done

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

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

Now count: how many keys did task 3 take, against the 115 characters of the finished line? If you keep `fast-settings.ps1`'s two lines, *Your Profile* shows how to make them part of every window.

## 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-fewer-keystrokes`), 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-fewer-keystrokes.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-fewer-keystrokes.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-fewer-keystrokes`, 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

Fast at the prompt isn't typing faster: it's typing less, finding what you already worked out, and letting PowerShell check each step before the next one runs.

## Key terms

- [Keyboard Shortcut](https://www.ask-codey.com/glossary/keyboard-shortcut)
- [PSReadLine](https://www.ask-codey.com/glossary/psreadline)
- [Set-PSReadLineOption](https://www.ask-codey.com/glossary/set-psreadlineoption)
- [Exit Code](https://www.ask-codey.com/glossary/exit-code-operating-system)
- [Pipeline Chain Operator](https://www.ask-codey.com/glossary/pipeline-chain-operator)

## Related

- [Keyboard Shortcuts at the Prompt](https://www.ask-codey.com/lessons/powershell-keyboard-shortcuts)
- [Predictions and History, Fully Used](https://www.ask-codey.com/lessons/powershell-predictions)
- [Did It Work? \`$?\`, \`$LASTEXITCODE\`, \`&&\` and \`||\`](https://www.ask-codey.com/lessons/powershell-did-it-work)
- [Finding Text: Select-String](https://www.ask-codey.com/lessons/powershell-select-string)
- [Your Profile](https://www.ask-codey.com/lessons/powershell-profile)

Source: https://www.ask-codey.com/lessons/exercise-powershell-fewer-keystrokes
