Comprehensive Guide to Initializing Arrays of Custom Objects in PowerShell

Nov 23, 2025 · Programming · 8 views · 7.8

Keywords: PowerShell | Custom Objects | Array Initialization | pscustomobject | PowerShell Classes

Abstract: This article provides an in-depth exploration of various methods for initializing arrays of custom objects in PowerShell, with detailed coverage of [pscustomobject] and custom class approaches. Through comprehensive code examples and comparative analysis, it examines the advantages, limitations, and version compatibility of different techniques, offering practical guidance for developers.

Introduction

In PowerShell script development, handling structured data is a common requirement. While many developers are accustomed to reading data from XML files and converting them into object arrays, there are scenarios where we need to create and initialize these data structures directly within scripts. This article systematically introduces several methods for initializing arrays of custom objects and analyzes their technical details.

Basic Method: Using pscustomobject

In PowerShell 3 and later versions, the [pscustomobject] type accelerator can be used to quickly create custom objects. This approach features concise syntax and is suitable for rapid prototyping:

$myitems = @(
    [pscustomobject]@{name="Joe";age=32;info="something about him"},
    [pscustomobject]@{name="Sue";age=29;info="something about her"},
    [pscustomobject]@{name="Cat";age=12;info="something else"}
)

The advantage of this method lies in its excellent code readability and maintainability. Each object is initialized using hash table literals, making property names and values immediately clear.

Version Compatibility Considerations

It's important to note that [pscustomobject] was introduced in PowerShell 3 and is not supported in earlier versions. Additionally, prior to PowerShell 6.1.0, single pscustomobject instances lacked Length and Count properties when returned:

$younger = $myitems | Where-Object { $_.age -lt 20 }
Write-Host "people younger than 20: $($younger.Length)"

The above code may not correctly display the count when a single object is returned. The solution is to use the array subexpression operator:

$younger = @($myitems | Where-Object { $_.age -lt 20 })

Object-Oriented Approach: Custom Classes

PowerShell 5 introduced class definition capabilities, providing stricter type checking and better encapsulation. First, define the Person class:

class Person {
    [string]$name
    [int]$age
    [string]$info
    
    Person([string]$name, [int]$age, [string]$info) {
        $this.name = $name
        $this.age = $age
        $this.info = $info
    }
}

Then initialize the array using constructors:

$myitems = @(
    [Person]::new("Joe", 32, "something about him"),
    [Person]::new("Sue", 29, "something about her"),
    [Person]::new("Cat", 12, "something else")
)

This approach avoids the property counting issues with pscustomobject and provides better type safety.

Hash Table Initialization for Class Objects

If a class defines a default constructor (or no constructors are defined), hash table syntax can also be used for initialization:

class Person {
    [string]$name
    [int]$age
    [string]$info
}

$myitems = @(
    [Person]@{name='Kevin'; age=36; info="something about him"},
    [Person]@{name='Sue'; age=29; info="something about her"},
    [Person]@{name='Cat'; age=12; info="something else"}
)

This method combines concise syntax with type safety, making it a recommended practice.

Performance and Maintainability Analysis

From a performance perspective, [pscustomobject] offers higher efficiency in simple scenarios, while custom classes provide greater advantages in complex business logic. From a maintainability standpoint, custom classes offer better code organization and refactoring capabilities.

Development teams should choose the appropriate method based on project requirements, PowerShell version compatibility needs, and long-term maintenance considerations. For rapid script development, [pscustomobject] is a good choice; for enterprise-level applications, custom classes are recommended.

Copyright Notice: All rights in this article are reserved by the operators of DevGex. Reasonable sharing and citation are welcome; any reproduction, excerpting, or re-publication without prior permission is prohibited.