PowerShell is built around objects rather than plain text. CmdLets like Get-Process return objects with properties (data) and methods (actions). Objects make it easy to pipe structured data between commands, and you can inspect any object's members with Get-Member CmdLet.

Creating custom objects

Use [PSCustomObject] with a hash table to create your own objects:

$person = [PSCustomObject]@{
    Name = "Alice"
    Age  = 30
    Role = "Forensic Analyst"
}

$person
$person.Name

Older alternative (less preferred):

$person = New-Object -TypeName PSObject -Property @{
    Name = "Alice"
    Age  = 30
}

Adding properties later

$person | Add-Member -MemberType NoteProperty -Name "Location" -Value "HQ"

Calculated properties

Calculated properties, most commonly used with Select-Object, let you create new fields from existing data:

Get-Process |
Select-Object Name, Id, @{Name="Status"; Expression={"Running"}} |
Select-Object -First 5

JSON serialization

CmdLet Purpose Example
ConvertFrom-Json JSON string → PS object '{"name":"Alice"}' \| ConvertFrom-Json
ConvertTo-Json PS object → JSON string $person \| ConvertTo-Json

Reading from a file:

Get-Content result.json | ConvertFrom-Json

Custom objects are essential when returning structured data from functions, grouping related fields, or preparing output for CSV/JSON/Excel, and they work naturally with pipeline cmdLets like PowerShell ForEach-Object CmdLet when processing collections.