Scope & evidence

PowerShell 5.1 and 7.x language concepts. In-memory illustrative examples; no remote systems or files are changed.

Stuart Kerr Spindlow has confirmed personal use and testing of the software covered by Happy SysAdm. The assessments here distinguish documented behaviour from measured results; worked scenarios are labelled and are not personal test records.

Start with the access pattern

For an administration report, a collection of consistently shaped custom objects is the strongest default because each row retains named, typed fields through filtering and export. Use a hashtable for an index into those records, not as a substitute for every row. Arrays are the simpler choice for an ordered list of values. These structures complement one another; choosing one exclusively usually makes either lookup or reporting less clear.

If you need to process a list of server names in order, an array is a natural fit. If you repeatedly ask who owns a named server, a hashtable expresses that lookup. If each server has a name, owner and environment, an object makes those fields explicit.

Do not choose a structure because its syntax is shortest. Think about missing values, duplicate keys, ordering and the shape expected by the next command. A report with inconsistent property names is harder to validate than one with a defined record layout.

Decision map

Choose by the question you need to ask

Array: which position?
Index 0 → app01; index 1 → db01. A sequence of values.
Hashtable: which key?
app01 → Operations; db01 → Database team. Look up a value by its key.
Object: which property?
Name: app01; Owner: Operations; Environment: Lab. One record with named fields.

Ordinary hashtable key order is not guaranteed. Keep commands and exports as objects until presentation.

Fictional records from the example below. These are data relationships, not captured PowerShell output. Evidence sources.

Build a small record deliberately

The example creates a sequence, a lookup and a record. The names are fictional. Array positions start at zero. Hashtable keys identify entries; assigning the same key again replaces its value, so a hashtable is not a safe way to preserve duplicate observations.

Use an ordered dictionary when the insertion order of keys matters. An ordinary hashtable should not be relied on for presentation order. Use Select-Object with an explicit property list when preparing an export so the output contract is visible.

$servers = @('app01', 'db01')
$owners = @{ app01 = 'Operations'; db01 = 'Database team' }
$record = [pscustomobject]@{
    Name = $servers[0]
    Owner = $owners['app01']
    Environment = 'Lab'
}
$record | Select-Object Name, Owner, Environment

Keep collections predictable

PowerShell often unwraps a pipeline result containing one item. Wrap a result in @() when downstream logic requires array behaviour for zero, one or many results. Test all three cases. For large collections, compare pipeline collection, array addition and a suitable generic list on the PowerShell release you actually use before choosing an optimisation.

Multidimensional arrays have fixed dimensions and are different from an array containing arrays. For uneven groups of records, nested collections or objects are often easier to understand. If you use a matrix, document which dimension represents which entity and test the boundary indexes.

Validate before exporting or acting

Check required properties, value types and uniqueness before a report drives changes. A missing owner is a data-quality failure, not an empty string to silently accept. Keep numbers as numbers until presentation, especially if you will sort or calculate totals.

Format-Table is for display, not the middle of an export pipeline. Retain the original objects until you reach a presentation or serialisation step. If you later use the records to change systems, add explicit target validation and a separate approval or dry-run stage.

Check shape before comparing speed

In an AI-run check on 23 September 2026 using PowerShell 7.6.6 on macOS 26.6.2, the worked example produced an array count of two, a hashtable count of two and the report record Name=app01, Owner=Operations, Environment=Lab. These are observed functional outputs from the exact synthetic example, not an execution on Windows or a performance benchmark. Storing the same hashtable key again replaces its value; it does not preserve two independent observations under that key.

The most useful correctness cases are zero results, one result and multiple results. A report pipeline that handles all three with the same record shape is preferable to a shorter expression that changes behaviour for a single server. Collection-building performance varies by PowerShell release and construction method; no timing advantage is claimed here.

References

Next useful steps

Read our editorial and corrections policy.