Hashtable vs PSCustomObject in PowerShell

PowerShell frequently works with structured data, and two common ways to store such data are Hashtables and PSCustomObjects. While both structures can look similar at first, they behave differently and serve different purposes.

Understanding the differences between these two approaches helps create scripts that are easier to read, easier to maintain, and better suited for working with the PowerShell pipeline.

Using Hashtables

A Hashtable is a collection of name-value pairs. The names and values do not need to be strings and can store many types of data. Hashtables are often used for quick lookups, configuration data, or parameter collections.

PowerShell
$user = @{
Firstname = "Ahmed"
Lastname = "Uzejnovic"
Department = "IT"
}
$user["Firstname"]

Because Hashtables are optimized for key-based access, retrieving values using a key is very efficient. This makes them well suited for storing configuration data or mapping information.

Using PSCustomObjects

A PSCustomObject represents a structured PowerShell object with properties. It behaves like the objects returned by most PowerShell cmdlets.

PowerShell
$user = [PSCustomObject]@{
Firstname = "Ahmed"
Lastname = "Uzejnovic"
Department = "IT"
}
$user.Firstname

Because PSCustomObjects expose properties, they integrate naturally with the PowerShell pipeline and can easily be processed by common cmdlets such as Select-Object, Where-Object, and Sort-Object.

Relationship Between Hashtables and PSCustomObjects

PSCustomObjects are effectively a superset of Hashtables. Hashtables store name-value pairs where the names and values do not need to be strings. PSCustomObjects extend this concept by allowing additional object functionality.

For example, PSCustomObjects support extended object members such as ScriptProperty, NoteProperty, and other metadata that does not exist in Hashtables.

At the same time, there are still constructs and cmdlets designed specifically for Hashtables and not for PSCustomObjects, and vice versa. Each structure therefore has strengths depending on the use case.

Working with the PowerShell Pipeline

One of the biggest advantages of PSCustomObjects is how well they work with the PowerShell pipeline.

PowerShell
$user = [PSCustomObject]@{
Firstname = "Ahmed"
Lastname = "Uzejnovic"
Department = "IT"
}
$user | Select-Object Firstname, Department

Because the data is stored as object properties, pipeline commands can easily access and process the information.

When to Use a Hashtable

Hashtables are often the best choice when:

  • Storing configuration data
  • Performing fast key-based lookups
  • Passing parameters dynamically to cmdlets
  • Building parameter splatting collections
PowerShell
$params = @{
Name = "TestUser"
Enabled = $true
}
New-ADUser @params

When to Use a PSCustomObject

PSCustomObjects are typically the better choice when:

  • Creating structured data for reporting
  • Working with the PowerShell pipeline
  • Exporting data to CSV, JSON, or other formats
  • Returning objects from functions
PowerShell
[PSCustomObject]@{
Server = "Server01"
Status = "Online"
Uptime = "12 Days"
}

Summary

Both Hashtables and PSCustomObjects are valuable tools in PowerShell. Hashtables are ideal for storing key-value data and performing fast lookups, while PSCustomObjects provide structured objects that integrate naturally with the PowerShell pipeline.

Choosing the appropriate structure depends on the scenario. Hashtables work well for configuration or parameter collections, while PSCustomObjects are better suited for structured data processing.

Leave a comment