# Lists and Lookups: Arrays and Hashtables

An array keeps several values in order, made with commas or @( ) and read by position from \[0\], and a hashtable, made with @{ }, keeps values under names so you can look one up by its name, the way you'd find a word in a dictionary.

Journeyman · PowerShell · Updated November 10, 2026

## After this lesson you can

- Make an array with commas or @( ), read its items by position from \[0\], and add to it with +=
- Make a hashtable with @{ }, look up a value by its key, and add or change a key
- Choose a single value, an array or a hashtable for the data a job needs

## Key takeaways

- An array is a list in order: `'kettle-bot', 'clock', 'bell'`, or `@( … )`. `[0]` is the first item and `[-1]` the last.
- `+=` adds an item to an array, `-contains` asks whether something is in it, and `.Count` says how many items it has.
- `@( )` makes sure you get a list, even of one item, so `[0]` is the first item and not the first letter.
- A hashtable, `@{ springs = 'drawer-2' }`, finds a value by its key: `$drawers['springs']` or `$drawers.springs`.
- A plain hashtable picks its own order; `[ordered]@{ }` keeps the order you wrote.

Look at your fridge. There's a list on it, the week's chores in order, and somewhere a note that says where things are: the spare key is on the hook, the batteries are in the junk drawer. One is a list you go through from the top; the other is a lookup where you find a thing by its name. Ada's workshop needs both: every morning her apprentice checks five machines in the same order, and whenever something breaks, the question is which drawer the springs are in. PowerShell has a box for each: an **array** for a list, a **hashtable** for a lookup. A tech keeps a list of computers to check in an array, and a developer keeps an app's settings in a hashtable.

## A list in order: an array

Commas between values make an array, a list in a single variable:

```powershell
$machines = 'kettle-bot', 'oil can', 'clock', 'gearbox', 'bell'
$machines.Count
$machines[0]
$machines[-1]
$machines[1..2]
```

```text
5
kettle-bot
bell
oil can
clock
```

Square brackets after the name pick an item by its position, its **index**, read "machines item 0". Counting starts at 0, so `[0]` is the first, and `[-1]` counts back from the end. `1..2`, read "1 to 2", picks a range. An index past the end, such as `$machines[5]`, gives nothing, with no error.

## Adding, and asking what's in it

`+=` adds an item at the end, and `-contains` asks whether a value is in the list:

```powershell
$machines += 'music box'
$machines.Count
$machines -contains 'clock'
$machines -contains 'owl'
```

```text
6
True
False
```

You can also write an array as `@( )`, read "a list of": `@('kettle-bot', 'clock')`, or `@()` for an empty one. Its real use is making sure you get a list. Text has indexes too, one per letter, so a single piece of text and a list of one look alike until you ask for `[0]`:

```powershell
$job = 'oil the gears'
$job[0]
$jobs = @('oil the gears')
$jobs[0]
```

```text
o
oil the gears
```

A command that might find one file or many goes in `@( )` for the same reason: `@(Get-ChildItem *.ps1)[0]` is always the first file.

## A lookup by name: a hashtable

A hashtable keeps each value under a name, its **key**. You've met one already: the `@{ Name = …; Expression = … }` in *Columns You Make Yourself: Calculated Properties*. `@{ }` is read "a lookup of", `=` joins a key to its value, and `;` separates the pairs:

```powershell
$drawers = @{ screws = 'drawer-1'; springs = 'drawer-2'; string = 'drawer-3' }
$drawers['springs']
$drawers.screws
```

```text
drawer-2
drawer-1
```

![Two ways to keep things. On the left, an array: five numbered slots in a row, 0 kettle-bot, 1 oil can, 2 clock, 3 gearbox and 4 bell, found by position. On the right, a hashtable: three drawers with name tags, screws in drawer-1, springs in drawer-2 and string in drawer-3, found by name](https://fsdtrainingmedia.blob.core.windows.net/public/images/2026/11/9f1c8fccc6214ee6b6c8dfcd562a35ac.webp)

Look a value up with the key in square brackets, or after a dot. Keys ignore capital letters, so `$drawers['SPRINGS']` works too. Setting a key that isn't there adds it, and setting one that is changes its value:

```powershell
$drawers['golden cog'] = 'drawer-3'
$drawers.springs = 'drawer-4'
$drawers.Count
$drawers
```

```text
4

Name                           Value
----                           -----
springs                        drawer-4
string                         drawer-3
screws                         drawer-1
golden cog                     drawer-3
```

A key with a space in it needs quotes. Notice the order: a hashtable keeps its pairs in an order of its own choosing, which can change from one run to the next. A key that isn't there gives nothing, and `$drawers.ContainsKey('hammer')` answers `False`.

## Keeping your order, and which one fits

When the order matters, put `[ordered]` in front:

```powershell
$week = [ordered]@{ Monday = 'oil the gears'; Wednesday = 'wind the clock'; Friday = 'polish the bell' }
$week
```

```text
Name                           Value
----                           -----
Monday                         oil the gears
Wednesday                      wind the clock
Friday                         polish the bell
```

So which box for the job? Ask how you'll find things in it:

| The job | The box | Example |
|---|---|---|
| One thing to remember | a plain variable | `$owl = "$HOME\…\clockwork-owl"` |
| Several things, gone through in order | an array | `$machines = 'kettle-bot', 'clock'` |
| Things you find by a name | a hashtable | `$drawers = @{ springs = 'drawer-2' }` |

Everything here works the same in Windows PowerShell 5.1 and on a Mac or Linux.

**Try it.** Make a hashtable of three things in your own home and where they live, such as `@{ passport = 'desk drawer'; charger = 'kitchen shelf' }`, then look one up by its key.

## Check yourself

2 questions to try on the lesson page.

## So what

A list you go through in order is an array; a lookup you search by name is a hashtable. Most of the data a script works with, from the files to check to the settings it reads, fits in one of the two.

## Key terms

- [Array](https://www.ask-codey.com/glossary/array-powershell)
- [Array Index](https://www.ask-codey.com/glossary/array-index-powershell)
- [Hashtable](https://www.ask-codey.com/glossary/hashtable)

## Cheat sheets

- [Lists and Lookups: Arrays and Hashtables](https://www.ask-codey.com/cheat-sheets/powershell-arrays-and-hashtables-cheat-sheet)

## Related

- [Variables: \`$name\`](https://www.ask-codey.com/lessons/powershell-variables)
- [Columns You Make Yourself: Calculated Properties](https://www.ask-codey.com/lessons/powershell-calculated-properties)
- [JSON: ConvertFrom-Json and ConvertTo-Json](https://www.ask-codey.com/lessons/powershell-json)

Source: https://www.ask-codey.com/lessons/powershell-arrays-and-hashtables
